From 5c33a274339dd7ffa5a8567e5fe44840984a4b74 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 4 Feb 2016 20:41:15 +0100
Subject: [PATCH] =?UTF-8?q?Fixed=20issue=20where=20newly=20created=20chann?=
 =?UTF-8?q?els=20wouldn=E2=80=99t=20be=20properly=20initialized.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../libquassel/client/BufferManager.java      | 13 +++++++++++
 .../de/kuschku/libquassel/client/Client.java  | 22 ++++++++++++++++++-
 .../backlogstorage/MemoryBacklogStorage.java  |  5 ++++-
 .../localtypes/buffers/Buffers.java           | 13 +++++++++++
 .../types/abstracts/AIrcChannel.java          | 10 ++++-----
 .../syncables/types/abstracts/AIrcUser.java   |  8 +++----
 .../syncables/types/abstracts/ANetwork.java   |  4 ++--
 .../types/impl/BufferViewConfig.java          | 18 ++++++++++++---
 .../syncables/types/impl/IrcChannel.java      |  6 ++---
 .../syncables/types/impl/IrcUser.java         | 13 +++++------
 10 files changed, 86 insertions(+), 26 deletions(-)

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 f415a1eda..8d8e10b31 100644
--- a/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
@@ -31,6 +31,7 @@ import java.util.Map;
 import java.util.Set;
 
 import de.kuschku.libquassel.localtypes.buffers.Buffer;
+import de.kuschku.libquassel.localtypes.buffers.Buffers;
 import de.kuschku.libquassel.localtypes.buffers.ChannelBuffer;
 import de.kuschku.libquassel.localtypes.buffers.QueryBuffer;
 import de.kuschku.libquassel.localtypes.buffers.StatusBuffer;
@@ -118,4 +119,16 @@ public class BufferManager {
                 createBuffer(new ChannelBuffer(info, ircChannel));
             }
     }
+
+    public void createBuffer(BufferInfo info) {
+        QNetwork network = client.networkManager().network(info.networkId());
+        if (network == null) return;
+        Buffer buffer = Buffers.fromType(info, network);
+        if (buffer == null) return;
+        createBuffer(buffer);
+    }
+
+    public boolean exists(BufferInfo info) {
+        return buffers.containsKey(info.id());
+    }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/client/Client.java b/app/src/main/java/de/kuschku/libquassel/client/Client.java
index 0684d5df6..6401bd5f6 100644
--- a/app/src/main/java/de/kuschku/libquassel/client/Client.java
+++ b/app/src/main/java/de/kuschku/libquassel/client/Client.java
@@ -24,6 +24,7 @@ package de.kuschku.libquassel.client;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.util.Log;
+import android.util.Pair;
 
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -57,6 +58,7 @@ import de.kuschku.libquassel.syncables.types.impl.NetworkConfig;
 import de.kuschku.libquassel.syncables.types.interfaces.QAliasManager;
 import de.kuschku.libquassel.syncables.types.interfaces.QBacklogManager;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferSyncer;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewManager;
 import de.kuschku.libquassel.syncables.types.interfaces.QIgnoreListManager;
 import de.kuschku.libquassel.syncables.types.interfaces.QNetwork;
@@ -80,8 +82,9 @@ public class Client extends AClient {
     private final NotificationManager notificationManager;
     private final List<String> initRequests = new LinkedList<>();
     private final List<Integer> backlogRequests = new LinkedList<>();
-    private final Map<String, List<SyncFunction>> bufferedSyncs = new HashMap<>();
     private final QBacklogManager backlogManager;
+    private final Map<String, List<SyncFunction>> bufferedSyncs = new HashMap<>();
+    private final Map<Integer, Pair<QBufferViewConfig, Integer>> bufferedBuffers = new HashMap<>();
     private QBufferViewManager bufferViewManager;
     // local
     private QBufferSyncer bufferSyncer;
@@ -442,4 +445,21 @@ public class Client extends AClient {
             bufferedSyncs.put(key, new LinkedList<>());
         bufferedSyncs.get(key).add(packedFunc);
     }
+
+    public void bufferBuffer(QBufferViewConfig bufferViewConfig, int bufferId, int pos) {
+        bufferedBuffers.put(bufferId, Pair.create(bufferViewConfig, pos));
+        Log.d("libquassel", "Queueing buffer: " + bufferId);
+    }
+
+    public void unbufferBuffer(BufferInfo info) {
+        if (!bufferManager().exists(info)) {
+            bufferManager().createBuffer(info);
+            Log.d("libquassel", "Creating buffer from message info: " + info.id());
+        }
+        if (bufferedBuffers.containsKey(info.id())) {
+            Pair<QBufferViewConfig, Integer> pair = bufferedBuffers.remove(info.id());
+            pair.first._addBuffer(info.id(), pair.second);
+            Log.d("libquassel", "Un-Queueing buffer: " + info.id());
+        }
+    }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java
index ee0e0c3f4..3d9642939 100644
--- a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java
+++ b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java
@@ -66,14 +66,17 @@ public class MemoryBacklogStorage implements BacklogStorage {
     @Override
     public void insertMessages(@IntRange(from = 0) int bufferId, @NonNull Message... messages) {
         ensureExisting(bufferId);
-        for (Message message : messages)
+        for (Message message : messages) {
+            client.unbufferBuffer(message.bufferInfo);
             backlogs.get(bufferId).add(message);
+        }
     }
 
     @Override
     public void insertMessages(@NonNull Message... messages) {
         for (Message message : messages) {
             ensureExisting(message.bufferInfo.id());
+            client.unbufferBuffer(message.bufferInfo);
             backlogs.get(message.bufferInfo.id()).add(message);
         }
     }
diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/Buffers.java b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/Buffers.java
index 6c6e03ea3..10627998e 100644
--- a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/Buffers.java
+++ b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/Buffers.java
@@ -34,6 +34,19 @@ public class Buffers {
 
     }
 
+    public static boolean exists(@NonNull BufferInfo info, @NonNull QNetwork network) {
+        switch (info.type()) {
+            case QUERY:
+                return info.name() != null && network.ircUser(info.name()) != null;
+            case CHANNEL:
+                return info.name() != null && network.ircChannel(info.name()) != null;
+            case STATUS:
+                return true;
+            default:
+                return false;
+        }
+    }
+
     @Nullable
     public static Buffer fromType(@NonNull BufferInfo info, @NonNull QNetwork network) {
         Buffer result;
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcChannel.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcChannel.java
index 75fdfbc0e..af5bf6437 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcChannel.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcChannel.java
@@ -55,13 +55,13 @@ public abstract class AIrcChannel<T extends AIrcChannel<T>> extends SyncableObje
     @Override
     public void joinIrcUser(QIrcUser ircuser) {
         _joinIrcUser(ircuser);
-        syncVar("joinIrcUser", ircuser);
+        syncVar("joinIrcUser", ircuser.nick());
     }
 
     @Override
     public void part(QIrcUser ircuser) {
         _part(ircuser);
-        syncVar("part", ircuser);
+        syncVar("part", ircuser.nick());
     }
 
     @Override
@@ -73,7 +73,7 @@ public abstract class AIrcChannel<T extends AIrcChannel<T>> extends SyncableObje
     @Override
     public void setUserModes(QIrcUser ircuser, String modes) {
         _setUserModes(ircuser, modes);
-        syncVar("setUserModes", ircuser, modes);
+        syncVar("setUserModes", ircuser.nick(), modes);
     }
 
     @Override
@@ -85,7 +85,7 @@ public abstract class AIrcChannel<T extends AIrcChannel<T>> extends SyncableObje
     @Override
     public void addUserMode(QIrcUser ircuser, String mode) {
         _addUserMode(ircuser, mode);
-        syncVar("addUserMode", ircuser, mode);
+        syncVar("addUserMode", ircuser.nick(), mode);
     }
 
     @Override
@@ -97,7 +97,7 @@ public abstract class AIrcChannel<T extends AIrcChannel<T>> extends SyncableObje
     @Override
     public void removeUserMode(QIrcUser ircuser, String mode) {
         _removeUserMode(ircuser, mode);
-        syncVar("removeUserMode", ircuser, mode);
+        syncVar("removeUserMode", ircuser.nick(), mode);
     }
 
     @Override
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcUser.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcUser.java
index a80207ee1..300175bca 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcUser.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcUser.java
@@ -127,13 +127,13 @@ public abstract class AIrcUser<T extends AIrcUser<T>> extends SyncableObject<T>
     @Override
     public void joinChannel(QIrcChannel channel) {
         _joinChannel(channel);
-        syncVar("joinChannel", channel);
+        syncVar("joinChannel", channel.name());
     }
 
     @Override
     public void joinChannel(QIrcChannel channel, boolean skip_channel_join) {
         _joinChannel(channel, skip_channel_join);
-        syncVar("joinChannel", channel, skip_channel_join);
+        syncVar("joinChannel", channel.name(), skip_channel_join);
     }
 
     @Override
@@ -145,7 +145,7 @@ public abstract class AIrcUser<T extends AIrcUser<T>> extends SyncableObject<T>
     @Override
     public void partChannel(QIrcChannel channel) {
         _partChannel(channel);
-        syncVar("partChannel", channel);
+        syncVar("partChannel", channel.name());
     }
 
     @Override
@@ -175,6 +175,6 @@ public abstract class AIrcUser<T extends AIrcUser<T>> extends SyncableObject<T>
     @Override
     public void partChannel(QIrcChannel channel, boolean skip_channel_part) {
         _partChannel(channel, skip_channel_part);
-        syncVar("partChannel", channel, skip_channel_part);
+        syncVar("partChannel", channel.name(), skip_channel_part);
     }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetwork.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetwork.java
index 291baa762..f7f196f36 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetwork.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetwork.java
@@ -251,12 +251,12 @@ public abstract class ANetwork<T extends ANetwork<T>> extends SyncableObject<T>
     @Override
     public void removeIrcChannel(QIrcChannel ircChannel) {
         _removeIrcChannel(ircChannel);
-        syncVar("removeIrcChannel", ircChannel);
+        syncVar("removeIrcChannel", ircChannel.name());
     }
 
     @Override
     public void removeIrcUser(QIrcUser ircuser) {
         _removeIrcUser(ircuser);
-        syncVar("removeIrcUser", ircuser);
+        syncVar("removeIrcUser", ircuser.nick());
     }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java
index 43ff8e364..2cfd900a0 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java
@@ -22,6 +22,7 @@
 package de.kuschku.libquassel.syncables.types.impl;
 
 import android.support.annotation.NonNull;
+import android.util.Log;
 
 import java.util.Collections;
 import java.util.List;
@@ -214,6 +215,11 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
 
     @Override
     public void _addBuffer(int bufferId, int pos) {
+        if (client.bufferManager().buffer(bufferId) == null) {
+            client.bufferBuffer(this, bufferId, pos);
+            return;
+        }
+
         if (buffers.contains(bufferId))
             return;
 
@@ -228,7 +234,7 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
         if (temporarilyRemovedBuffers.contains(bufferId))
             temporarilyRemovedBuffers.remove(bufferId);
 
-        buffers.add(bufferId, pos);
+        buffers.add(pos, bufferId);
     }
 
     @Override
@@ -269,13 +275,19 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
 
     @Override
     public void _removeBuffer(int bufferId) {
-        if (buffers.contains(bufferId))
-            buffers.remove(buffers.indexOf(bufferId));
+        Log.d("after", String.valueOf(buffers));
+
+        int index;
+        if ((index = buffers.indexOf(bufferId)) != -1) {
+            buffers.remove(index);
+        }
 
         if (removedBuffers.contains(bufferId))
             removedBuffers.remove(bufferId);
 
         temporarilyRemovedBuffers.add(bufferId);
+
+        Log.d("after", String.valueOf(buffers));
         _update();
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcChannel.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcChannel.java
index ee9ff1506..520837eb3 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcChannel.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcChannel.java
@@ -294,15 +294,15 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
     public void _part(@NonNull QIrcUser ircuser) {
         if (isKnownUser(ircuser)) {
             userModes.remove(ircuser);
-            ircuser.partChannel(this);
+            ircuser._partChannel(this);
 
             if (network().isMe(ircuser) || userModes.isEmpty()) {
                 Set<QIrcUser> users = userModes.keySet();
                 userModes.clear();
                 for (QIrcUser user : users) {
-                    user.partChannel(this, true);
+                    user._partChannel(this, true);
                 }
-                network().removeIrcChannel(this);
+                network()._removeIrcChannel(this);
             }
             _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 23666611e..063c4344c 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
@@ -68,7 +68,7 @@ public class IrcUser extends AIrcUser<IrcUser> {
     private boolean encrypted;
     private QNetwork network;
     private Set<Character> userModes;
-    private Set<QIrcChannel> channels;
+    private Set<QIrcChannel> channels = new HashSet<>();
 
     public IrcUser(String server, String ircOperator, boolean away, int lastAwayMessage, DateTime idleTime, String whoisServiceReply, String suserHost, String nick, String realName, String awayMessage, DateTime loginTime, boolean encrypted, List<String> channels, String host, String userModes, String user) {
         this.server = server;
@@ -367,7 +367,7 @@ public class IrcUser extends AIrcUser<IrcUser> {
         if (!channels.contains(channel)) {
             channels.add(channel);
             if (!skip_channel_join)
-                channel.joinIrcUser(this);
+                channel._joinIrcUser(this);
         }
         _update();
     }
@@ -389,9 +389,9 @@ public class IrcUser extends AIrcUser<IrcUser> {
         if (channels.contains(channel)) {
             channels.remove(channel);
             if (!skip_channel_part)
-                channel.joinIrcUser(this);
+                channel._part(this);
             if (channels.isEmpty() && !network().isMe(this))
-                quit();
+                _quit();
         }
         _update();
     }
@@ -407,9 +407,9 @@ public class IrcUser extends AIrcUser<IrcUser> {
         List<QIrcChannel> channels = new ArrayList<>(this.channels);
         this.channels.clear();
         for (QIrcChannel channel : channels) {
-            channel.part(this);
+            channel._part(this);
         }
-        network().removeIrcUser(this);
+        network()._removeIrcUser(this);
         _update();
     }
 
@@ -436,7 +436,6 @@ public class IrcUser extends AIrcUser<IrcUser> {
         this.network = network;
         this.client = client;
 
-        channels = new HashSet<>();
         if (cachedChannels != null)
         for (String channelName : cachedChannels) {
             channels.add(network().newIrcChannel(channelName));
-- 
GitLab