summary refs log tree commit diff
path: root/src/ReadReceiptsModel.cpp
diff options
context:
space:
mode:
authorLoren Burkholder <computersemiexpert@outlook.com>2021-07-23 18:11:33 -0400
committerLoren Burkholder <computersemiexpert@outlook.com>2021-07-29 21:07:16 -0400
commit4dd994ae009b622cd35e292d1170a3f60a26c4d6 (patch)
treeaf3a825decdd96963a9cf0c9efcd57a3d8db1ed4 /src/ReadReceiptsModel.cpp
parentPort to explicit connect syntax (diff)
downloadnheko-4dd994ae009b622cd35e292d1170a3f60a26c4d6.tar.xz
QML the read receipts list
There are probably a few things wrong with this, but I'm going to call it good enough for an initial commit
Diffstat (limited to 'src/ReadReceiptsModel.cpp')
-rw-r--r--src/ReadReceiptsModel.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/ReadReceiptsModel.cpp b/src/ReadReceiptsModel.cpp
new file mode 100644
index 00000000..293733d3
--- /dev/null
+++ b/src/ReadReceiptsModel.cpp
@@ -0,0 +1,120 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "ReadReceiptsModel.h"
+
+#include <QLocale>
+
+#include "Cache.h"
+#include "Logging.h"
+#include "Utils.h"
+
+ReadReceiptsModel::ReadReceiptsModel(QString event_id, QString room_id, QObject *parent)
+  : QAbstractListModel{parent}
+  , event_id_{event_id}
+  , room_id_{room_id}
+{
+        try {
+                addUsers(cache::readReceipts(event_id, room_id));
+        } catch (const lmdb::error &) {
+                nhlog::db()->warn("failed to retrieve read receipts for {} {}",
+                                  event_id.toStdString(),
+                                  room_id_.toStdString());
+
+                return;
+        }
+}
+
+ReadReceiptsModel::~ReadReceiptsModel()
+{
+        for (const auto &item : readReceipts_)
+                item->deleteLater();
+}
+
+QHash<int, QByteArray>
+ReadReceiptsModel::roleNames() const
+{
+        return {{Mxid, "mxid"},
+                {DisplayName, "displayName"},
+                {AvatarUrl, "avatarUrl"},
+                {Timestamp, "timestamp"}};
+}
+
+QVariant
+ReadReceiptsModel::data(const QModelIndex &index, int role) const
+{
+        if (!index.isValid() || index.row() >= (int)readReceipts_.size() || index.row() < 0)
+                return {};
+
+        switch (role) {
+        case Mxid:
+                return readReceipts_[index.row()]->mxid();
+        case DisplayName:
+                return readReceipts_[index.row()]->displayName();
+        case AvatarUrl:
+                return readReceipts_[index.row()]->avatarUrl();
+        case Timestamp:
+                // the uint64_t to QVariant conversion was ambiguous, so...
+                return readReceipts_[index.row()]->timestamp();
+        default:
+                return {};
+        }
+}
+
+void
+ReadReceiptsModel::addUsers(
+  const std::multimap<uint64_t, std::string, std::greater<uint64_t>> &users)
+{
+        std::multimap<uint64_t, std::string, std::greater<uint64_t>> unshown;
+        for (const auto &user : users) {
+                if (users_.find(user.first) == users_.end())
+                        unshown.emplace(user);
+        }
+
+        beginInsertRows(
+          QModelIndex{}, readReceipts_.length(), readReceipts_.length() + unshown.size() - 1);
+
+        for (const auto &user : unshown)
+                readReceipts_.push_back(
+                  new ReadReceipt{QString::fromStdString(user.second), room_id_, user.first, this});
+
+        users_.merge(unshown);
+
+        endInsertRows();
+}
+
+ReadReceipt::ReadReceipt(QString mxid, QString room_id, uint64_t timestamp, QObject *parent)
+  : QObject{parent}
+  , mxid_{mxid}
+  , room_id_{room_id}
+  , displayName_{cache::displayName(room_id_, mxid_)}
+  , avatarUrl_{cache::avatarUrl(room_id_, mxid_)}
+  , timestamp_{timestamp}
+{}
+
+QString
+ReadReceipt::timestamp() const
+{
+        return dateFormat(QDateTime::fromMSecsSinceEpoch(timestamp_));
+}
+
+QString
+ReadReceipt::dateFormat(const QDateTime &then) const
+{
+        auto now  = QDateTime::currentDateTime();
+        auto days = then.daysTo(now);
+
+        if (days == 0)
+                return tr("Today %1")
+                  .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat));
+        else if (days < 2)
+                return tr("Yesterday %1")
+                  .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat));
+        else if (days < 7)
+                return QString("%1 %2")
+                  .arg(then.toString("dddd"))
+                  .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat));
+
+        return QLocale::system().toString(then.time(), QLocale::ShortFormat);
+}