From ee7cd4d60bae87d132ea9698c68fbdb9b418a74d Mon Sep 17 00:00:00 2001
From: Mario Danic <mario@lovelyhq.com>
Date: Wed, 18 Dec 2019 05:10:41 +0100
Subject: [PATCH] Further performance improvements

---
 .../1.json                                    | 12 +++++-
 .../talk/controllers/ChatController.kt        |  5 +--
 .../talk/models/ExternalSignalingServer.kt    | 22 ++++++++++-
 .../json/capabilities/Capabilities.java       | 20 +++++++++-
 .../capabilities/NotificationsCapability.java | 14 +++++++
 .../json/capabilities/SpreedCapability.java   | 15 ++++++++
 .../json/capabilities/ThemingCapability.java  | 24 ++++++++++++
 .../json/push/PushConfigurationState.kt       | 27 +++++++++++++-
 .../talk/newarch/features/chat/ChatView.kt    |  4 +-
 .../ConversationsListView.kt                  |  1 +
 .../newarch/local/dao/ConversationsDao.kt     |  2 +-
 .../local/models/ConversationEntity.kt        |  3 +-
 .../talk/newarch/local/models/UserNgEntity.kt | 37 +++++++++++++------
 13 files changed, 161 insertions(+), 25 deletions(-)

diff --git a/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json b/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json
index 8aa661eec..157e8c95b 100644
--- a/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json
+++ b/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json
@@ -2,7 +2,7 @@
   "formatVersion": 1,
   "database": {
     "version": 1,
-    "identityHash": "0bb77d35d80f74e97eea4a5415d9a102",
+    "identityHash": "479fc8a763ef590d3126641f418e5730",
     "entities": [
       {
         "tableName": "conversations",
@@ -180,6 +180,14 @@
               "token"
             ],
             "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_conversations_user_id_token` ON `${TABLE_NAME}` (`user_id`, `token`)"
+          },
+          {
+            "name": "index_conversations_user_id",
+            "unique": false,
+            "columnNames": [
+              "user_id"
+            ],
+            "createSql": "CREATE INDEX IF NOT EXISTS `index_conversations_user_id` ON `${TABLE_NAME}` (`user_id`)"
           }
         ],
         "foreignKeys": [
@@ -375,7 +383,7 @@
     "views": [],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0bb77d35d80f74e97eea4a5415d9a102')"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '479fc8a763ef590d3126641f418e5730')"
     ]
   }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
index b72ef9f62..4a4409fa7 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
@@ -66,13 +66,12 @@ import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.models.json.mention.Mention
 import com.nextcloud.talk.newarch.local.models.UserNgEntity
 import com.nextcloud.talk.newarch.local.models.getCredentials
-import com.nextcloud.talk.newarch.local.models.maxMessageLength
+import com.nextcloud.talk.newarch.local.models.getMaxMessageLength
 import com.nextcloud.talk.newarch.utils.Images
 import com.nextcloud.talk.presenters.MentionAutocompletePresenter
 import com.nextcloud.talk.utils.*
 import com.nextcloud.talk.utils.DrawableUtils.getDrawableResourceIdForMimeType
 import com.nextcloud.talk.utils.bundle.BundleKeys
-import com.nextcloud.talk.utils.database.user.UserUtils
 import com.nextcloud.talk.utils.text.Spans
 import com.nextcloud.talk.webrtc.MagicWebSocketInstance
 import com.nextcloud.talk.webrtc.WebSocketConnectionHelper
@@ -428,7 +427,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
         })
 
         val filters = arrayOfNulls<InputFilter>(1)
-        val lengthFilter = conversationUser?.maxMessageLength() ?: 1000
+        val lengthFilter = conversationUser?.getMaxMessageLength() ?: 1000
 
 
         filters[0] = InputFilter.LengthFilter(lengthFilter)
diff --git a/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt b/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt
index 609bd1198..48012fa42 100644
--- a/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt
+++ b/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt
@@ -36,4 +36,24 @@ data class ExternalSignalingServer(
         var externalSignalingServer: String? = null,
         @JsonField(name = ["externalSignalingTicket"])
         var externalSignalingTicket: String? = null
-) : Parcelable
+
+
+) : Parcelable {
+        override fun equals(other: Any?): Boolean {
+                if (this === other) return true
+                if (javaClass != other?.javaClass) return false
+
+                other as ExternalSignalingServer
+
+                if (externalSignalingServer != other.externalSignalingServer) return false
+                if (externalSignalingTicket != other.externalSignalingTicket) return false
+
+                return true
+        }
+
+        override fun hashCode(): Int {
+                var result = externalSignalingServer?.hashCode() ?: 0
+                result = 31 * result + (externalSignalingTicket?.hashCode() ?: 0)
+                return result
+        }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.java b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.java
index e5399de5f..7494dee1d 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.java
+++ b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.java
@@ -27,6 +27,7 @@ import org.parceler.Parcel;
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.Objects;
 
 import lombok.Data;
 
@@ -43,6 +44,21 @@ public class Capabilities {
     @JsonField(name = "theming")
     public ThemingCapability themingCapability;
 
-    @JsonField(name = "external")
-    public HashMap<String, List<String>> externalCapability;
+    /*@JsonField(name = "external")
+    public HashMap<String, List<String>> externalCapability;*/
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof Capabilities)) return false;
+        Capabilities that = (Capabilities) o;
+        return Objects.equals(spreedCapability, that.spreedCapability) &&
+                Objects.equals(notificationsCapability, that.notificationsCapability) &&
+                Objects.equals(themingCapability, that.themingCapability);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(spreedCapability, notificationsCapability, themingCapability);
+    }
 }
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/NotificationsCapability.java b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/NotificationsCapability.java
index e275c4347..a42778589 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/NotificationsCapability.java
+++ b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/NotificationsCapability.java
@@ -26,6 +26,7 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
 import org.parceler.Parcel;
 
 import java.util.List;
+import java.util.Objects;
 
 import lombok.Data;
 
@@ -35,4 +36,17 @@ import lombok.Data;
 public class NotificationsCapability {
     @JsonField(name = "ocs-endpoints")
     public List<String> features;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof NotificationsCapability)) return false;
+        NotificationsCapability that = (NotificationsCapability) o;
+        return Objects.equals(features, that.features);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(features);
+    }
 }
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/SpreedCapability.java b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/SpreedCapability.java
index 088bfb713..7d7a854ea 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/SpreedCapability.java
+++ b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/SpreedCapability.java
@@ -27,6 +27,7 @@ import org.parceler.Parcel;
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.Objects;
 
 import lombok.Data;
 
@@ -39,4 +40,18 @@ public class SpreedCapability {
 
     @JsonField(name = "config")
     public HashMap<String, HashMap<String, String>> config;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof SpreedCapability)) return false;
+        SpreedCapability that = (SpreedCapability) o;
+        return Objects.equals(features, that.features) &&
+                Objects.equals(config, that.config);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(features, config);
+    }
 }
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/ThemingCapability.java b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/ThemingCapability.java
index 58c0f5fe2..ac197ab0a 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/ThemingCapability.java
+++ b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/ThemingCapability.java
@@ -25,6 +25,8 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
 
 import org.parceler.Parcel;
 
+import java.util.Objects;
+
 import lombok.Data;
 
 @Parcel
@@ -60,4 +62,26 @@ class ThemingCapability {
 
     @JsonField(name = "background-default")
     boolean backgroundDefault;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ThemingCapability)) return false;
+        ThemingCapability that = (ThemingCapability) o;
+        return backgroundPlain == that.backgroundPlain &&
+                backgroundDefault == that.backgroundDefault &&
+                Objects.equals(name, that.name) &&
+                Objects.equals(url, that.url) &&
+                Objects.equals(slogan, that.slogan) &&
+                Objects.equals(color, that.color) &&
+                Objects.equals(colorText, that.colorText) &&
+                Objects.equals(colorElement, that.colorElement) &&
+                Objects.equals(logo, that.logo) &&
+                Objects.equals(background, that.background);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name, url, slogan, color, colorText, colorElement, logo, background, backgroundPlain, backgroundDefault);
+    }
 }
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/push/PushConfigurationState.kt b/app/src/main/java/com/nextcloud/talk/models/json/push/PushConfigurationState.kt
index 587a26267..9aaec666e 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/push/PushConfigurationState.kt
+++ b/app/src/main/java/com/nextcloud/talk/models/json/push/PushConfigurationState.kt
@@ -42,4 +42,29 @@ class PushConfigurationState(
         var userPublicKey: String? = null,
         @JsonField(name = ["usesRegularPass"])
         var usesRegularPass: Boolean = false
-) : Parcelable
\ No newline at end of file
+
+) : Parcelable {
+        override fun equals(other: Any?): Boolean {
+                if (this === other) return true
+                if (javaClass != other?.javaClass) return false
+
+                other as PushConfigurationState
+
+                if (pushToken != other.pushToken) return false
+                if (deviceIdentifier != other.deviceIdentifier) return false
+                if (deviceIdentifierSignature != other.deviceIdentifierSignature) return false
+                if (userPublicKey != other.userPublicKey) return false
+                if (usesRegularPass != other.usesRegularPass) return false
+
+                return true
+        }
+
+        override fun hashCode(): Int {
+                var result = pushToken?.hashCode() ?: 0
+                result = 31 * result + (deviceIdentifier?.hashCode() ?: 0)
+                result = 31 * result + (deviceIdentifierSignature?.hashCode() ?: 0)
+                result = 31 * result + (userPublicKey?.hashCode() ?: 0)
+                result = 31 * result + usesRegularPass.hashCode()
+                return result
+        }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatView.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatView.kt
index c95057bd1..dcfff8154 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatView.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatView.kt
@@ -29,7 +29,7 @@ import com.nextcloud.talk.models.json.mention.Mention
 import com.nextcloud.talk.newarch.conversationsList.mvp.BaseView
 import com.nextcloud.talk.newarch.local.models.UserNgEntity
 import com.nextcloud.talk.newarch.local.models.getCredentials
-import com.nextcloud.talk.newarch.local.models.maxMessageLength
+import com.nextcloud.talk.newarch.local.models.getMaxMessageLength
 import com.nextcloud.talk.newarch.mvvm.ext.initRecyclerView
 import com.nextcloud.talk.newarch.utils.Images
 import com.nextcloud.talk.presenters.MentionAutocompletePresenter
@@ -160,7 +160,7 @@ class ChatView : BaseView(), MessageHolders.ContentChecker<IMessage>, MessagesLi
             })
 
             val filters = arrayOfNulls<InputFilter>(1)
-            val lengthFilter = viewModel.user.maxMessageLength()
+            val lengthFilter = viewModel.user.getMaxMessageLength()
 
 
             filters[0] = InputFilter.LengthFilter(lengthFilter)
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
index 95fe9740d..52156a968 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
@@ -216,6 +216,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
             })
 
             conversationsLiveData.observe(this@ConversationsListView, Observer {
+                Log.d("MARIO", "TRIGGER")
                 if (it.isEmpty()) {
                     if (viewState.value != LOADED_EMPTY) {
                         viewState.value = LOADED_EMPTY
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/dao/ConversationsDao.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/dao/ConversationsDao.kt
index 8b85ee396..61bb0ff97 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/local/dao/ConversationsDao.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/dao/ConversationsDao.kt
@@ -90,4 +90,4 @@ abstract class ConversationsDao {
         saveConversationsWithInsert(*conversationsWithTimestampApplied.toTypedArray())
         deleteConversationsForUserWithTimestamp(userId, timestamp)
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt
index 458d0e5fb..5e6780291 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt
@@ -20,7 +20,6 @@
 
 package com.nextcloud.talk.newarch.local.models
 
-import android.util.Log
 import androidx.room.*
 import androidx.room.ForeignKey.CASCADE
 import com.nextcloud.talk.models.json.chat.ChatMessage
@@ -31,7 +30,7 @@ import java.util.*
 
 @Entity(
         tableName = "conversations",
-        indices = [Index(value = ["user_id", "token"], unique = true)],
+        indices = [Index(value = ["user_id", "token"], unique = true), Index(value = ["user_id"])],
         foreignKeys = [ForeignKey(
                 entity = UserNgEntity::class,
                 parentColumns = arrayOf("id"),
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/models/UserNgEntity.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/models/UserNgEntity.kt
index 42572dfb0..9b0b60f91 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/local/models/UserNgEntity.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/models/UserNgEntity.kt
@@ -51,6 +51,7 @@ data class UserNgEntity(
         ) var externalSignaling: ExternalSignalingServer? = null,
         @ColumnInfo(name = "status") var status: UserStatus? = null
 ) : Parcelable {
+
     fun hasSpreedFeatureCapability(capabilityName: String): Boolean {
         val capabilityExists = capabilities?.spreedCapability?.features?.contains(capabilityName)
         if (capabilityExists != null) {
@@ -60,20 +61,34 @@ data class UserNgEntity(
         }
 
     }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as UserNgEntity
+
+        if (userId != other.userId) return false
+        if (username != other.username) return false
+        if (baseUrl != other.baseUrl) return false
+        if (token != other.token) return false
+        if (displayName != other.displayName) return false
+        if (pushConfiguration != other.pushConfiguration) return false
+        if (capabilities != other.capabilities) return false
+        if (clientCertificate != other.clientCertificate) return false
+        //if (externalSignaling != other.externalSignaling) return false
+        if (status != other.status) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        return userId.hashCode()
+    }
 }
 
 fun UserNgEntity.getCredentials() = ApiUtils.getCredentials(username, token)
 
-fun UserNgEntity.hasExternalCapability(capabilityName: String): Boolean {
-    val capabilityExists = capabilities?.externalCapability?.get("v1")
-            ?.contains(capabilityName)
-    if (capabilityExists != null) {
-        return capabilityExists
-    } else {
-        return false
-    }
-}
-
 fun UserNgEntity.hasSpreedFeatureCapability(capabilityName: String): Boolean {
     val capabilityExists = capabilities?.spreedCapability?.features?.contains(capabilityName)
     if (capabilityExists != null) {
@@ -83,7 +98,7 @@ fun UserNgEntity.hasSpreedFeatureCapability(capabilityName: String): Boolean {
     }
 }
 
-fun UserNgEntity.maxMessageLength(): Int {
+fun UserNgEntity.getMaxMessageLength(): Int {
     val maxLength = capabilities?.spreedCapability?.config?.get("chat")
             ?.get("max-length")
     return maxLength?.toInt() ?: 1000