summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2020-09-24 21:36:43 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2020-09-24 21:36:43 +0200
commit4802c340091a5ce18cf444792eed45f461cd6f6b (patch)
tree6c3ff6843df6bc719e97d246a7a1cc70494b7dd5 /src/timeline
parentSimplify outbound session setup (diff)
parentTranslated using Weblate (French) (diff)
downloadnheko-4802c340091a5ce18cf444792eed45f461cd6f6b.tar.xz
Merge remote-tracking branch 'origin/master' into cross-signing
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/EventStore.cpp2
-rw-r--r--src/timeline/TimelineModel.cpp82
-rw-r--r--src/timeline/TimelineModel.h14
-rw-r--r--src/timeline/TimelineViewManager.cpp41
-rw-r--r--src/timeline/TimelineViewManager.h33
5 files changed, 150 insertions, 22 deletions
diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp

index af1f7b23..298e0d18 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp
@@ -573,7 +573,7 @@ EventStore::decryptEvent(const IdIndex &idx, room_id_, index.sender_key); dummy.content.body = - tr("-- Reply attack! This message index was reused! --").toStdString(); + tr("-- Replay attack! This message index was reused! --").toStdString(); break; case olm::DecryptionErrorCode::UnknownFingerprint: // TODO: don't fail, just show in UI. diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index ddd238b9..af26a543 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -566,6 +566,25 @@ TimelineModel::fetchMore(const QModelIndex &) } void +TimelineModel::syncState(const mtx::responses::State &s) +{ + using namespace mtx::events; + + for (const auto &e : s.events) { + if (std::holds_alternative<StateEvent<state::Avatar>>(e)) + emit roomAvatarUrlChanged(); + else if (std::holds_alternative<StateEvent<state::Name>>(e)) + emit roomNameChanged(); + else if (std::holds_alternative<StateEvent<state::Topic>>(e)) + emit roomTopicChanged(); + else if (std::holds_alternative<StateEvent<state::Member>>(e)) { + emit roomAvatarUrlChanged(); + emit roomNameChanged(); + } + } +} + +void TimelineModel::addEvents(const mtx::responses::Timeline &timeline) { if (timeline.events.empty()) @@ -574,6 +593,7 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) events.handleSync(timeline); using namespace mtx::events; + for (auto e : timeline.events) { if (auto encryptedEvent = std::get_if<EncryptedEvent<msg::Encrypted>>(&e)) { MegolmSessionIndex index; @@ -597,6 +617,16 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) emit newCallEvent(event); }, e); + else if (std::holds_alternative<StateEvent<state::Avatar>>(e)) + emit roomAvatarUrlChanged(); + else if (std::holds_alternative<StateEvent<state::Name>>(e)) + emit roomNameChanged(); + else if (std::holds_alternative<StateEvent<state::Topic>>(e)) + emit roomTopicChanged(); + else if (std::holds_alternative<StateEvent<state::Member>>(e)) { + emit roomAvatarUrlChanged(); + emit roomNameChanged(); + } } updateLastMessage(); } @@ -737,12 +767,6 @@ TimelineModel::formatDateSeparator(QDate date) const return date.toString(fmt); } -QString -TimelineModel::escapeEmoji(QString str) const -{ - return utils::replaceEmoji(str); -} - void TimelineModel::viewRawMessage(QString id) const { @@ -1440,7 +1464,7 @@ TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg) QStringList uidWithoutLast; auto formatUser = [this, bg](const QString &user_id) -> QString { - auto uncoloredUsername = escapeEmoji(displayName(user_id)); + auto uncoloredUsername = utils::replaceEmoji(displayName(user_id)); QString prefix = QString("<font color=\"%1\">").arg(manager_->userColor(user_id, bg).name()); @@ -1490,7 +1514,7 @@ TimelineModel::formatJoinRuleEvent(QString id) return ""; QString user = QString::fromStdString(event->sender); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); switch (event->content.join_rule) { case mtx::events::state::JoinRule::Public: @@ -1515,7 +1539,7 @@ TimelineModel::formatGuestAccessEvent(QString id) return ""; QString user = QString::fromStdString(event->sender); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); switch (event->content.guest_access) { case mtx::events::state::AccessState::CanJoin: @@ -1540,7 +1564,7 @@ TimelineModel::formatHistoryVisibilityEvent(QString id) return ""; QString user = QString::fromStdString(event->sender); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); switch (event->content.history_visibility) { case mtx::events::state::Visibility::WorldReadable: @@ -1573,7 +1597,7 @@ TimelineModel::formatPowerLevelEvent(QString id) return ""; QString user = QString::fromStdString(event->sender); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); // TODO: power levels rendering is actually a bit complex. work on this later. return tr("%1 has changed the room's permissions.").arg(name); @@ -1602,7 +1626,7 @@ TimelineModel::formatMemberEvent(QString id) } QString user = QString::fromStdString(event->state_key); - QString name = escapeEmoji(displayName(user)); + QString name = utils::replaceEmoji(displayName(user)); QString rendered; // see table https://matrix.org/docs/spec/client_server/latest#m-room-member @@ -1675,3 +1699,37 @@ TimelineModel::formatMemberEvent(QString id) return rendered; } + +QString +TimelineModel::roomName() const +{ + auto info = cache::getRoomInfo({room_id_.toStdString()}); + + if (!info.count(room_id_)) + return ""; + else + return QString::fromStdString(info[room_id_].name); +} + +QString +TimelineModel::roomAvatarUrl() const +{ + auto info = cache::getRoomInfo({room_id_.toStdString()}); + + if (!info.count(room_id_)) + return ""; + else + return QString::fromStdString(info[room_id_].avatar_url); +} + +QString +TimelineModel::roomTopic() const +{ + auto info = cache::getRoomInfo({room_id_.toStdString()}); + + if (!info.count(room_id_)) + return ""; + else + return utils::replaceEmoji(utils::linkifyMessage( + utils::escapeBlacklistedHtml(QString::fromStdString(info[room_id_].topic)))); +} diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 61d00df9..3234a20c 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h
@@ -146,6 +146,9 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QString reply READ reply WRITE setReply NOTIFY replyChanged RESET resetReply) Q_PROPERTY( bool paginationInProgress READ paginationInProgress NOTIFY paginationInProgressChanged) + Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) + Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) + Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) public: explicit TimelineModel(TimelineViewManager *manager, @@ -203,7 +206,6 @@ public: Q_INVOKABLE QString formatGuestAccessEvent(QString id); Q_INVOKABLE QString formatPowerLevelEvent(QString id); - Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE void viewRawMessage(QString id) const; Q_INVOKABLE void viewDecryptedRawMessage(QString id) const; Q_INVOKABLE void openUserProfile(QString userid); @@ -226,6 +228,7 @@ public: void updateLastMessage(); void addEvents(const mtx::responses::Timeline &events); + void syncState(const mtx::responses::State &state); template<class T> void sendMessageEvent(const T &content, mtx::events::EventType eventType); RelatedInfo relatedInfo(QString id); @@ -262,6 +265,11 @@ public slots: void setDecryptDescription(bool decrypt) { decryptDescription = decrypt; } void clearTimeline() { events.clearTimeline(); } + QString roomName() const; + QString roomTopic() const; + QString roomAvatarUrl() const; + QString roomId() const { return room_id_; } + private slots: void addPendingMessage(mtx::events::collections::TimelineEvents event); @@ -282,6 +290,10 @@ signals: void addPendingMessageToStore(mtx::events::collections::TimelineEvents event); void updateFlowEventId(std::string event_id); + void roomNameChanged(); + void roomTopicChanged(); + void roomAvatarUrlChanged(); + private: template<typename T> void sendEncryptedMessage(mtx::events::RoomEvent<T> msg, mtx::events::EventType eventType); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 97c119bf..03dd4773 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp
@@ -13,6 +13,7 @@ #include "ColorImageProvider.h" #include "DelegateChooser.h" #include "Logging.h" +#include "MainWindow.h" #include "MatrixClient.h" #include "MxcImageProvider.h" #include "UserSettingsPage.h" @@ -102,7 +103,7 @@ TimelineViewManager::userStatus(QString id) const TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettings, CallManager *callManager, - QWidget *parent) + ChatPage *parent) : imgProvider(new MxcImageProvider()) , colorImgProvider(new ColorImageProvider()) , blurhashProvider(new BlurhashProvider()) @@ -189,11 +190,8 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin view->engine()->addImageProvider("blurhash", blurhashProvider); view->setSource(QUrl("qrc:///qml/TimelineView.qml")); - connect(dynamic_cast<ChatPage *>(parent), - &ChatPage::themeChanged, - this, - &TimelineViewManager::updateColorPalette); - connect(dynamic_cast<ChatPage *>(parent), + connect(parent, &ChatPage::themeChanged, this, &TimelineViewManager::updateColorPalette); + connect(parent, &ChatPage::decryptSidebarChanged, this, &TimelineViewManager::updateEncryptedDescriptions); @@ -295,7 +293,7 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin } } }); - connect(dynamic_cast<ChatPage *>(parent), &ChatPage::loggedOut, this, [this]() { + connect(parent, &ChatPage::loggedOut, this, [this]() { isInitialSync_ = true; emit initialSyncChanged(true); }); @@ -313,6 +311,7 @@ TimelineViewManager::sync(const mtx::responses::Rooms &rooms) &TimelineModel::newCallEvent, callManager_, &CallManager::syncEvent); + room_model->syncState(room.state); room_model->addEvents(room.timeline); if (!isInitialSync_) disconnect(room_model.data(), @@ -363,6 +362,12 @@ TimelineViewManager::setHistoryView(const QString &room_id) } } +QString +TimelineViewManager::escapeEmoji(QString str) const +{ + return utils::replaceEmoji(str); +} + void TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) const { @@ -402,6 +407,28 @@ TimelineViewManager::openLink(QString link) const } void +TimelineViewManager::openInviteUsersDialog() +{ + MainWindow::instance()->openInviteUsersDialog( + [this](const QStringList &invitees) { emit inviteUsers(invitees); }); +} +void +TimelineViewManager::openMemberListDialog() const +{ + MainWindow::instance()->openMemberListDialog(timeline_->roomId()); +} +void +TimelineViewManager::openLeaveRoomDialog() const +{ + MainWindow::instance()->openLeaveRoomDialog(timeline_->roomId()); +} +void +TimelineViewManager::openRoomSettings() const +{ + MainWindow::instance()->openRoomSettings(timeline_->roomId()); +} + +void TimelineViewManager::updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids) { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 19406872..4779d3cd 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h
@@ -22,6 +22,7 @@ class BlurhashProvider; class CallManager; class ColorImageProvider; class UserSettings; +class ChatPage; class DeviceVerificationList : public QObject { @@ -45,11 +46,13 @@ class TimelineViewManager : public QObject TimelineModel *timeline MEMBER timeline_ READ activeTimeline NOTIFY activeTimelineChanged) Q_PROPERTY( bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged) + Q_PROPERTY( + bool isNarrowView MEMBER isNarrowView_ READ isNarrowView NOTIFY narrowViewChanged) public: TimelineViewManager(QSharedPointer<UserSettings> userSettings, CallManager *callManager, - QWidget *parent = nullptr); + ChatPage *parent = nullptr); QWidget *getWidget() const { return container; } void sync(const mtx::responses::Rooms &rooms); @@ -59,14 +62,21 @@ public: Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; } Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; } + bool isNarrowView() const { return isNarrowView_; } Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const; Q_INVOKABLE QColor userColor(QString id, QColor background); + Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE QString userPresence(QString id) const; Q_INVOKABLE QString userStatus(QString id) const; Q_INVOKABLE void openLink(QString link) const; + Q_INVOKABLE void openInviteUsersDialog(); + Q_INVOKABLE void openMemberListDialog() const; + Q_INVOKABLE void openLeaveRoomDialog() const; + Q_INVOKABLE void openRoomSettings() const; + signals: void clearRoomMessageCount(QString roomid); void updateRoomsLastMessage(QString roomid, const DescInfo &info); @@ -79,6 +89,9 @@ signals: QString userId, QString deviceId, bool isRequest = false); + void inviteUsers(QStringList users); + void showRoomList(); + void narrowViewChanged(); public slots: void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids); @@ -128,6 +141,23 @@ public slots: timeline_->clearTimeline(); } + void enableBackButton() + { + if (isNarrowView_) + return; + isNarrowView_ = true; + emit narrowViewChanged(); + } + void disableBackButton() + { + if (!isNarrowView_) + return; + isNarrowView_ = false; + emit narrowViewChanged(); + } + + void backToRooms() { emit showRoomList(); } + private: #ifdef USE_QUICK_VIEW QQuickView *view; @@ -145,6 +175,7 @@ private: CallManager *callManager_ = nullptr; bool isInitialSync_ = true; + bool isNarrowView_ = false; QSharedPointer<UserSettings> settings; QHash<QString, QColor> userColors;