summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2020-01-17 01:25:14 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2020-01-17 01:25:14 +0100
commitfe912240bc1ab89b8a20ce87d5183f328f704d23 (patch)
treefd86e16977dc068c8ad404dc4ede4eb6640374de /src/timeline
parentRemove embedded fonts (diff)
downloadnheko-fe912240bc1ab89b8a20ce87d5183f328f704d23.tar.xz
Move typing display to qml
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/TimelineModel.cpp30
-rw-r--r--src/timeline/TimelineModel.h13
-rw-r--r--src/timeline/TimelineViewManager.cpp18
3 files changed, 58 insertions, 3 deletions
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp

index 08c29927..2fd4b6d4 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -1388,3 +1388,33 @@ TimelineModel::cacheMedia(QString eventId) emit mediaCached(mxcUrl, filename.filePath()); }); } + +QString +TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg) +{ + QString temp = + tr("%1 and %2 are typing", + "Multiple users are typing. First argument is a comma separated list of potentially " + "multiple users. Second argument is the last user of that list. (If only one user is " + "typing, %1 is empty. You should still use it in your string though to silence Qt " + "warnings.)", + users.size()); + + if (users.empty()) { + return ""; + } + + QStringList uidWithoutLast; + + auto formatUser = [this, bg](const QString &user_id) -> QString { + return QString("<font color=\"%1\">%2</font>") + .arg(userColor(user_id, bg).name()) + .arg(escapeEmoji(displayName(user_id).toHtmlEscaped())); + }; + + for (size_t i = 0; i + 1 < users.size(); i++) { + uidWithoutLast.append(formatUser(users[i])); + } + + return temp.arg(uidWithoutLast.join(", ")).arg(formatUser(users.back())); +} diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index ae505c17..6d351359 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h
@@ -120,6 +120,8 @@ class TimelineModel : public QAbstractListModel Q_OBJECT Q_PROPERTY( int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) + Q_PROPERTY(std::vector<QString> typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY + typingUsersChanged) public: explicit TimelineModel(TimelineViewManager *manager, QString room_id, QObject *parent = 0); @@ -162,6 +164,7 @@ public: Q_INVOKABLE QString displayName(QString id) const; Q_INVOKABLE QString avatarUrl(QString id) const; Q_INVOKABLE QString formatDateSeparator(QDate date) const; + Q_INVOKABLE QString formatTypingUsers(const std::vector<QString> &users, QColor bg); Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE void viewRawMessage(QString id) const; @@ -183,6 +186,14 @@ public slots: int currentIndex() const { return idToIndex(currentId); } void markEventsAsRead(const std::vector<QString> &event_ids); QVariantMap getDump(QString eventId) const; + void updateTypingUsers(const std::vector<QString> &users) + { + if (this->typingUsers_ != users) { + this->typingUsers_ = users; + emit typingUsersChanged(typingUsers_); + } + } + std::vector<QString> typingUsers() const { return typingUsers_; } private slots: // Add old events at the top of the timeline. @@ -202,6 +213,7 @@ signals: void mediaCached(QString mxcUrl, QString cacheUrl); void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo); void replyFetched(QString requestingEvent, mtx::events::collections::TimelineEvents event); + void typingUsersChanged(std::vector<QString> users); private: DecryptionResult decryptEvent( @@ -232,6 +244,7 @@ private: QHash<QString, QColor> userColors; QString currentId; + std::vector<QString> typingUsers_; TimelineViewManager *manager_; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index ddbc6af8..c7a4e50e 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp
@@ -8,6 +8,7 @@ #include "ColorImageProvider.h" #include "DelegateChooser.h" #include "Logging.h" +#include "MatrixClient.h" #include "MxcImageProvider.h" #include "UserSettingsPage.h" #include "dialogs/ImageOverlay.h" @@ -92,10 +93,21 @@ TimelineViewManager::TimelineViewManager(QWidget *parent) void TimelineViewManager::sync(const mtx::responses::Rooms &rooms) { - for (auto it = rooms.join.cbegin(); it != rooms.join.cend(); ++it) { + for (const auto &[room_id, room] : rooms.join) { // addRoom will only add the room, if it doesn't exist - addRoom(QString::fromStdString(it->first)); - models.value(QString::fromStdString(it->first))->addEvents(it->second.timeline); + addRoom(QString::fromStdString(room_id)); + const auto &room_model = models.value(QString::fromStdString(room_id)); + room_model->addEvents(room.timeline); + + if (ChatPage::instance()->userSettings()->isTypingNotificationsEnabled()) { + std::vector<QString> typing; + typing.reserve(room.ephemeral.typing.size()); + for (const auto &user : room.ephemeral.typing) { + if (user != http::client()->user_id().to_string()) + typing.push_back(QString::fromStdString(user)); + } + room_model->updateTypingUsers(typing); + } } this->isInitialSync_ = false;