From e18c329741b9c276273405d0b2bd04f9d2afa8bd Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Mon, 28 Jun 2021 21:39:39 -0400
Subject: [PATCH] smartlist: prevent excessive updates to items during
 reselection

Only save the draft if it changes and filter for index on data
changed signals before updating the avatar.

Change-Id: Ia23a35b512249e4b7953e3a2cef2cedbda386e65
---
 src/lrcinstance.cpp                           |  6 +++
 .../components/SmartListItemDelegate.qml      | 15 +++----
 src/selectablelistproxymodel.cpp              | 45 +++++++++++--------
 src/selectablelistproxymodel.h                |  4 ++
 4 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/src/lrcinstance.cpp b/src/lrcinstance.cpp
index f68c85237..3b07d3308 100644
--- a/src/lrcinstance.cpp
+++ b/src/lrcinstance.cpp
@@ -402,6 +402,12 @@ LRCInstance::setContentDraft(const QString& convUid,
                              const QString& content)
 {
     auto draftKey = accountId + "_" + convUid;
+
+    // prevent a senseless dataChanged signal from the
+    // model if nothing has changed
+    if (contentDrafts_[draftKey] == content)
+        return;
+
     contentDrafts_[draftKey] = content;
     // this signal is only needed to update the current smartlist
     Q_EMIT draftSaved(convUid);
diff --git a/src/mainview/components/SmartListItemDelegate.qml b/src/mainview/components/SmartListItemDelegate.qml
index 28ac45cb8..ab24f1beb 100644
--- a/src/mainview/components/SmartListItemDelegate.qml
+++ b/src/mainview/components/SmartListItemDelegate.qml
@@ -54,14 +54,13 @@ ItemDelegate {
 
             Connections {
                 target: root.ListView.view.model
-                function onDataChanged(index) {
-                    var model = root.ListView.view.model
-                    avatar.updateImage(URI === undefined ?
-                                           model.data(index, ConversationList.URI):
-                                           URI,
-                                       PictureUid === undefined ?
-                                           model.data(index, ConversationList.PictureUid):
-                                           PictureUid)
+                function onDataChanged(idx) {
+                    // TODO: currently the avatar dispaly mechanism requires
+                    // that each dataChanged signal is caught by and induces an
+                    // updateImage call per smartlist item. Once this is fixed
+                    // we can filter for the current delegate's index like:
+                    // if (idx.row !== index) return
+                    avatar.updateImage(URI, PictureUid)
                 }
             }
 
diff --git a/src/selectablelistproxymodel.cpp b/src/selectablelistproxymodel.cpp
index 5c7f0199a..fc2b34a69 100644
--- a/src/selectablelistproxymodel.cpp
+++ b/src/selectablelistproxymodel.cpp
@@ -30,24 +30,21 @@ void
 SelectableListProxyModel::bindSourceModel(QAbstractListModel* model)
 {
     setSourceModel(model);
-    connect(
-        sourceModel(),
-        &QAbstractListModel::dataChanged,
-        this,
-        [this] { updateSelection(); },
-        Qt::UniqueConnection);
-    connect(
-        model,
-        &QAbstractListModel::rowsInserted,
-        this,
-        [this] { updateSelection(); },
-        Qt::UniqueConnection);
-    connect(
-        model,
-        &QAbstractListModel::rowsRemoved,
-        this,
-        [this] { updateSelection(true); },
-        Qt::UniqueConnection);
+    connect(sourceModel(),
+            &QAbstractListModel::dataChanged,
+            this,
+            &SelectableListProxyModel::onModelUpdated,
+            Qt::UniqueConnection);
+    connect(model,
+            &QAbstractListModel::rowsInserted,
+            this,
+            &SelectableListProxyModel::onModelUpdated,
+            Qt::UniqueConnection);
+    connect(model,
+            &QAbstractListModel::rowsRemoved,
+            this,
+            &SelectableListProxyModel::onModelTrimmed,
+            Qt::UniqueConnection);
     connect(sourceModel(),
             &QAbstractListModel::modelReset,
             this,
@@ -152,6 +149,18 @@ SelectableListProxyModel::updateSelection(bool rowsRemoved)
     }
 }
 
+void
+SelectableListProxyModel::onModelUpdated()
+{
+    updateSelection();
+}
+
+void
+SelectableListProxyModel::onModelTrimmed()
+{
+    updateSelection(true);
+}
+
 SelectableListProxyGroupModel::SelectableListProxyGroupModel(QList<SelectableListProxyModel*> models,
                                                              QObject* parent)
     : QObject(parent)
diff --git a/src/selectablelistproxymodel.h b/src/selectablelistproxymodel.h
index ae252bf11..a8e775dd7 100644
--- a/src/selectablelistproxymodel.h
+++ b/src/selectablelistproxymodel.h
@@ -52,6 +52,10 @@ public Q_SLOTS:
 Q_SIGNALS:
     void validSelectionChanged();
 
+private Q_SLOTS:
+    void onModelUpdated();
+    void onModelTrimmed();
+
 private:
     QPersistentModelIndex selectedSourceIndex_;
 };
-- 
GitLab