From f349b0cce0335c2c9f6aaabfad9315e80bc72677 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 18 Jun 2021 14:05:52 +0200 Subject: Hide spaces by default, unless they are in the current space filter --- src/timeline/TimelineModel.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/timeline/TimelineModel.cpp') diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 99547b15..1ecb6cdf 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -320,6 +320,10 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj { lastMessage_.timestamp = 0; + if (auto create = + cache::client()->getStateEvent(room_id.toStdString())) + this->isSpace_ = create->content.type == mtx::events::state::room_type::space; + connect( this, &TimelineModel::redactionFailed, -- cgit 1.5.1 From 884fb74d2d1386c7355a709b3972619f5bd0f78a Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 18 Jun 2021 16:22:06 +0200 Subject: Add a basic 'Space page' --- resources/qml/ChatPage.qml | 2 +- resources/qml/RoomList.qml | 2 +- resources/qml/TimelineView.qml | 63 +++++++++++++++++++++++++++++++++++++++++- src/Cache.cpp | 7 +++++ src/Cache_p.h | 1 + src/timeline/TimelineModel.cpp | 8 ++++++ src/timeline/TimelineModel.h | 3 ++ 7 files changed, 83 insertions(+), 3 deletions(-) (limited to 'src/timeline/TimelineModel.cpp') diff --git a/resources/qml/ChatPage.qml b/resources/qml/ChatPage.qml index df2bf41f..cd323a97 100644 --- a/resources/qml/ChatPage.qml +++ b/resources/qml/ChatPage.qml @@ -71,7 +71,7 @@ Rectangle { AdaptiveLayoutElement { id: timlineViewC - minimumWidth: fontMetrics.averageCharacterWidth * 40 + Nheko.avatarSize + 2* Nheko.paddingMedium + minimumWidth: fontMetrics.averageCharacterWidth * 40 + Nheko.avatarSize + 2 * Nheko.paddingMedium TimelineView { id: timeline diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index 99e0ed41..d69f608b 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -254,9 +254,9 @@ Page { Label { id: timestamp + visible: !model.isInvite && !model.isSpace width: visible ? 0 : undefined - Layout.alignment: Qt.AlignRight | Qt.AlignBottom font.pixelSize: fontMetrics.font.pixelSize * 0.9 color: roomItem.unimportantText diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 90e28166..703f2fac 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -41,7 +41,8 @@ Item { ColumnLayout { id: timelineLayout - visible: room != null + visible: room != null && !room.isSpace + enabled: visible anchors.fill: parent spacing: 0 @@ -127,6 +128,66 @@ Item { } + ColumnLayout { + id: contentLayout1 + + visible: room != null && room.isSpace + enabled: visible + anchors.fill: parent + anchors.margins: Nheko.paddingLarge + spacing: Nheko.paddingLarge + + Avatar { + url: room.roomAvatarUrl.replace("mxc://", "image://MxcImage/") + displayName: room ? room.roomName : "" + height: 130 + width: 130 + Layout.alignment: Qt.AlignHCenter + enabled: false + } + + MatrixText { + text: room ? room.roomName : "" + font.pixelSize: 24 + Layout.alignment: Qt.AlignHCenter + } + + MatrixText { + text: qsTr("%1 member(s)").arg(room ? room.roomMemberCount : 0) + Layout.alignment: Qt.AlignHCenter + } + + ScrollView { + //Layout.maximumHeight: 75 + Layout.alignment: Qt.AlignHCenter + width: parent.width + + TextArea { + text: TimelineManager.escapeEmoji(room ? room.roomTopic : "") + wrapMode: TextEdit.WordWrap + textFormat: TextEdit.RichText + readOnly: true + background: null + selectByMouse: true + color: Nheko.colors.text + horizontalAlignment: TextEdit.AlignHCenter + onLinkActivated: Nheko.openLink(link) + + CursorShape { + anchors.fill: parent + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + } + + } + + } + + Item { + Layout.fillHeight: true + } + + } + NhekoDropArea { anchors.fill: parent roomid: room ? room.roomId() : "" diff --git a/src/Cache.cpp b/src/Cache.cpp index 8b1798d6..144a2d9a 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1772,6 +1772,13 @@ Cache::relatedEvents(const std::string &room_id, const std::string &event_id) return related_ids; } +size_t +Cache::memberCount(const std::string &room_id) +{ + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + return getMembersDb(txn, room_id).size(txn); +} + QMap Cache::roomInfo(bool withInvites) { diff --git a/src/Cache_p.h b/src/Cache_p.h index e35e78ec..cfcf9c9e 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -101,6 +101,7 @@ public: std::vector getMembers(const std::string &room_id, std::size_t startIndex = 0, std::size_t len = 30); + size_t memberCount(const std::string &room_id); void saveState(const mtx::responses::Sync &res); bool isInitialized(); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 1ecb6cdf..13919e6d 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -774,6 +774,7 @@ TimelineModel::syncState(const mtx::responses::State &s) } else if (std::holds_alternative>(e)) { emit roomAvatarUrlChanged(); emit roomNameChanged(); + emit roomMemberCountChanged(); } } } @@ -830,6 +831,7 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) } else if (std::holds_alternative>(e)) { emit roomAvatarUrlChanged(); emit roomNameChanged(); + emit roomMemberCountChanged(); } } updateLastMessage(); @@ -1935,3 +1937,9 @@ TimelineModel::roomTopic() const return utils::replaceEmoji(utils::linkifyMessage( QString::fromStdString(info[room_id_].topic).toHtmlEscaped())); } + +int +TimelineModel::roomMemberCount() const +{ + return (int)cache::client()->memberCount(room_id_.toStdString()); +} diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 42aa136f..3392d474 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -161,6 +161,7 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) + Q_PROPERTY(int roomMemberCount READ roomMemberCount NOTIFY roomMemberCountChanged) Q_PROPERTY(bool isSpace READ isSpace CONSTANT) Q_PROPERTY(InputBar *input READ input CONSTANT) Q_PROPERTY(Permissions *permissions READ permissions NOTIFY permissionsChanged) @@ -264,6 +265,7 @@ public: DescInfo lastMessage() const { return lastMessage_; } bool isSpace() const { return isSpace_; } + int roomMemberCount() const; public slots: void setCurrentIndex(int index); @@ -350,6 +352,7 @@ signals: void roomNameChanged(); void roomTopicChanged(); void roomAvatarUrlChanged(); + void roomMemberCountChanged(); void permissionsChanged(); void forwardToRoom(mtx::events::collections::TimelineEvents *e, QString roomId); -- cgit 1.5.1 From d30446a8b39c70f87fad34b0c1958236c9f227cc Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 19 Jun 2021 01:46:23 +0200 Subject: Don't spam key requests directly after startup --- src/timeline/EventStore.cpp | 15 +++++++++++++++ src/timeline/EventStore.h | 2 ++ src/timeline/TimelineModel.cpp | 6 ++++++ 3 files changed, 23 insertions(+) (limited to 'src/timeline/TimelineModel.cpp') diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp index 04f7ef76..9a91ff79 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp @@ -675,6 +675,9 @@ EventStore::decryptEvent(const IdIndex &idx, index.room_id, index.session_id, e.sender); + // we may not want to request keys during initial sync and such + if (suppressKeyRequests) + break; // TODO: Check if this actually works and look in key backup auto copy = e; copy.room_id = room_id_; @@ -816,6 +819,18 @@ EventStore::decryptEvent(const IdIndex &idx, return asCacheEntry(std::move(decryptionResult.event.value())); } +void +EventStore::enableKeyRequests(bool suppressKeyRequests_) +{ + if (!suppressKeyRequests_) { + for (const auto &key : decryptedEvents_.keys()) + if (key.room == this->room_id_) + decryptedEvents_.remove(key); + suppressKeyRequests = false; + } else + suppressKeyRequests = true; +} + mtx::events::collections::TimelineEvents * EventStore::get(std::string id, std::string_view related_to, bool decrypt, bool resolve_edits) { diff --git a/src/timeline/EventStore.h b/src/timeline/EventStore.h index d9bb86cb..7c404102 100644 --- a/src/timeline/EventStore.h +++ b/src/timeline/EventStore.h @@ -115,6 +115,7 @@ public slots: void addPending(mtx::events::collections::TimelineEvents event); void receivedSessionKey(const std::string &session_id); void clearTimeline(); + void enableKeyRequests(bool suppressKeyRequests_); private: std::vector edits(const std::string &event_id); @@ -142,4 +143,5 @@ private: std::string current_txn; int current_txn_error_count = 0; bool noMoreMessages = false; + bool suppressKeyRequests = true; }; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 13919e6d..067f219a 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -379,6 +379,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj connect(&events, &EventStore::updateFlowEventId, this, [this](std::string event_id) { this->updateFlowEventId(event_id); }); + // When a message is sent, check if the current edit/reply relates to that message, // and update the event_id so that it points to the sent message and not the pending one. connect(&events, @@ -395,6 +396,11 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj } }); + connect(manager_, + &TimelineViewManager::initialSyncChanged, + &events, + &EventStore::enableKeyRequests); + showEventTimer.callOnTimeout(this, &TimelineModel::scrollTimerEvent); } -- cgit 1.5.1