summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLoren Burkholder <computersemiexpert@outlook.com>2021-07-28 21:31:37 -0400
committerLoren Burkholder <computersemiexpert@outlook.com>2021-07-29 21:07:52 -0400
commit7e538851d6e3779434722e56a968e9f8b8a9da0d (patch)
tree8147ac95a7e17b66c398cb3d09185d3194f5520b /src
parentReset model instead of doing weird convoluted updates (diff)
downloadnheko-7e538851d6e3779434722e56a968e9f8b8a9da0d.tar.xz
Use a QSortFilterProxyModel instead of resetting the model
Diffstat (limited to 'src')
-rw-r--r--src/ReadReceiptsModel.cpp53
-rw-r--r--src/ReadReceiptsModel.h27
-rw-r--r--src/timeline/TimelineModel.cpp2
-rw-r--r--src/timeline/TimelineModel.h2
-rw-r--r--src/timeline/TimelineViewManager.cpp6
5 files changed, 66 insertions, 24 deletions
diff --git a/src/ReadReceiptsModel.cpp b/src/ReadReceiptsModel.cpp
index 936c6d61..0be22be2 100644
--- a/src/ReadReceiptsModel.cpp
+++ b/src/ReadReceiptsModel.cpp
@@ -46,10 +46,13 @@ ReadReceiptsModel::update()
 QHash<int, QByteArray>
 ReadReceiptsModel::roleNames() const
 {
-        return {{Mxid, "mxid"},
-                {DisplayName, "displayName"},
-                {AvatarUrl, "avatarUrl"},
-                {Timestamp, "timestamp"}};
+        // Note: RawTimestamp is purposely not included here
+        return {
+          {Mxid, "mxid"},
+          {DisplayName, "displayName"},
+          {AvatarUrl, "avatarUrl"},
+          {Timestamp, "timestamp"},
+        };
 }
 
 QVariant
@@ -67,6 +70,8 @@ ReadReceiptsModel::data(const QModelIndex &index, int role) const
                 return cache::avatarUrl(room_id_, readReceipts_[index.row()].first);
         case Timestamp:
                 return dateFormat(readReceipts_[index.row()].second);
+        case RawTimestamp:
+                return readReceipts_[index.row()].second;
         default:
                 return {};
         }
@@ -76,21 +81,22 @@ void
 ReadReceiptsModel::addUsers(
   const std::multimap<uint64_t, std::string, std::greater<uint64_t>> &users)
 {
-        beginResetModel();
+        auto newReceipts = users.size() - readReceipts_.size();
 
-        readReceipts_.clear();
-        for (const auto &user : users) {
-                readReceipts_.push_back({QString::fromStdString(user.second),
-                                         QDateTime::fromMSecsSinceEpoch(user.first)});
-        }
+        if (newReceipts > 0) {
+                beginInsertRows(
+                  QModelIndex{}, readReceipts_.size(), readReceipts_.size() + newReceipts - 1);
 
-        std::sort(readReceipts_.begin(),
-                  readReceipts_.end(),
-                  [](const QPair<QString, QDateTime> &a, const QPair<QString, QDateTime> &b) {
-                          return a.second > b.second;
-                  });
+                for (const auto &user : users) {
+                        QPair<QString, QDateTime> item = {
+                          QString::fromStdString(user.second),
+                          QDateTime::fromMSecsSinceEpoch(user.first)};
+                        if (!readReceipts_.contains(item))
+                                readReceipts_.push_back(item);
+                }
 
-        endResetModel();
+                endInsertRows();
+        }
 }
 
 QString
@@ -112,3 +118,18 @@ ReadReceiptsModel::dateFormat(const QDateTime &then) const
 
         return QLocale::system().toString(then.time(), QLocale::ShortFormat);
 }
+
+ReadReceiptsProxy::ReadReceiptsProxy(QString event_id, QString room_id, QObject *parent)
+  : QSortFilterProxyModel{parent}
+  , model_{event_id, room_id, this}
+{
+        setSourceModel(&model_);
+        setSortRole(ReadReceiptsModel::RawTimestamp);
+}
+
+bool
+ReadReceiptsProxy::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
+{
+        // since we are sorting from greatest to least timestamp, return something that looks totally backwards!
+        return source_left.data().toULongLong() > source_right.data().toULongLong();
+}
diff --git a/src/ReadReceiptsModel.h b/src/ReadReceiptsModel.h
index f2e39f88..9e26bcd5 100644
--- a/src/ReadReceiptsModel.h
+++ b/src/ReadReceiptsModel.h
@@ -8,15 +8,13 @@
 #include <QAbstractListModel>
 #include <QDateTime>
 #include <QObject>
+#include <QSortFilterProxyModel>
 #include <QString>
 
 class ReadReceiptsModel : public QAbstractListModel
 {
         Q_OBJECT
 
-        Q_PROPERTY(QString eventId READ eventId CONSTANT)
-        Q_PROPERTY(QString roomId READ roomId CONSTANT)
-
 public:
         enum Roles
         {
@@ -24,6 +22,7 @@ public:
                 DisplayName,
                 AvatarUrl,
                 Timestamp,
+                RawTimestamp,
         };
 
         explicit ReadReceiptsModel(QString event_id, QString room_id, QObject *parent = nullptr);
@@ -51,4 +50,26 @@ private:
         QVector<QPair<QString, QDateTime>> readReceipts_;
 };
 
+class ReadReceiptsProxy : public QSortFilterProxyModel
+{
+        Q_OBJECT
+
+        Q_PROPERTY(QString eventId READ eventId CONSTANT)
+        Q_PROPERTY(QString roomId READ roomId CONSTANT)
+
+public:
+        explicit ReadReceiptsProxy(QString event_id, QString room_id, QObject *parent = nullptr);
+
+        QString eventId() const { return event_id_; }
+        QString roomId() const { return room_id_; }
+
+        bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
+
+private:
+        QString event_id_;
+        QString room_id_;
+
+        ReadReceiptsModel model_;
+};
+
 #endif // READRECEIPTSMODEL_H
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index f5737063..6ae0c4d1 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -1092,7 +1092,7 @@ TimelineModel::relatedInfo(QString id)
 void
 TimelineModel::showReadReceipts(QString id)
 {
-        emit openReadReceiptsDialog(new ReadReceiptsModel{id, roomId(), this});
+        emit openReadReceiptsDialog(new ReadReceiptsProxy{id, roomId(), this});
 }
 
 void
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 82fce257..0d5f7109 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -349,7 +349,7 @@ signals:
         void typingUsersChanged(std::vector<QString> users);
         void replyChanged(QString reply);
         void editChanged(QString reply);
-        void openReadReceiptsDialog(ReadReceiptsModel *rr);
+        void openReadReceiptsDialog(ReadReceiptsProxy *rr);
         void paginationInProgressChanged(const bool);
         void newCallEvent(const mtx::events::collections::TimelineEvents &event);
         void scrollToIndex(int index);
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 58b0d5a8..76bc127e 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -206,12 +206,12 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
           0,
           "InviteesModel",
           "InviteesModel needs to be instantiated on the C++ side");
-        qmlRegisterUncreatableType<ReadReceiptsModel>(
+        qmlRegisterUncreatableType<ReadReceiptsProxy>(
           "im.nheko",
           1,
           0,
-          "ReadReceiptsModel",
-          "ReadReceiptsModel needs to be instantiated on the C++ side");
+          "ReadReceiptsProxy",
+          "ReadReceiptsProxy needs to be instantiated on the C++ side");
 
         static auto self = this;
         qmlRegisterSingletonType<MainWindow>(