diff options
-rw-r--r-- | resources/qml/TimelineView.qml | 25 | ||||
-rw-r--r-- | src/Cache.cpp | 15 | ||||
-rw-r--r-- | src/CacheStructs.h | 1 | ||||
-rw-r--r-- | src/Cache_p.h | 13 | ||||
-rw-r--r-- | src/timeline/RoomlistModel.cpp | 46 | ||||
-rw-r--r-- | src/timeline/RoomlistModel.h | 6 |
6 files changed, 102 insertions, 4 deletions
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 24489d0b..18085f28 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -283,6 +283,29 @@ Item { onClicked: TimelineManager.openLeaveRoomDialog(room.roomId) } + RowLayout { + Layout.alignment: Qt.AlignHCenter + spacing: Nheko.paddingMedium + visible: roomPreview && roomPreview.isInvite && reasonField.showReason + + MatrixText { + text: qsTr("Invited by %1 (%2)").arg(TimelineManager.escapeEmoji(inviterAvatar.displayName)).arg(TimelineManager.escapeEmoji(TimelineManager.htmlEscape(inviterAvatar.userid))) + } + Avatar { + id: inviterAvatar + + Layout.alignment: Qt.AlignHCenter + displayName: roomPreview?.inviterDisplayName ?? "" + enabled: true + height: 48 + roomid: preview.roomId + url: (roomPreview?.inviterAvatarUrl ?? "").replace("mxc://", "image://MxcImage/") + userid: roomPreview?.inviterUserId ?? "" + width: 48 + + onClicked: TimelineManager.openGlobalUserProfile(roomPreview.inviterUserId) + } + } ScrollView { id: reasonField @@ -312,7 +335,7 @@ Item { Layout.leftMargin: Nheko.paddingLarge Layout.rightMargin: Nheko.paddingLarge text: reasonField.showReason ? qsTr("Hide invite reason") : qsTr("Show invite reason") - visible: preview.reason !== "" + visible: roomPreview && roomPreview.isInvite onClicked: { reasonField.showReason = !reasonField.showReason; diff --git a/src/Cache.cpp b/src/Cache.cpp index 7671af02..f4aad6b3 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -2128,8 +2128,16 @@ Cache::saveInvite(lmdb::txn &txn, auto display_name = msg->content.display_name.empty() ? msg->state_key : msg->content.display_name; - MemberInfo tmp{ - display_name, msg->content.avatar_url, msg->content.reason, msg->content.is_direct}; + std::string inviter = ""; + if (msg->content.membership == mtx::events::state::Membership::Invite) { + inviter = msg->sender; + } + + MemberInfo tmp{display_name, + msg->content.avatar_url, + inviter, + msg->content.reason, + msg->content.is_direct}; membersdb.put(txn, msg->state_key, nlohmann::json(tmp).dump()); } else { @@ -5173,6 +5181,8 @@ to_json(nlohmann::json &j, const MemberInfo &info) { j["name"] = info.name; j["avatar_url"] = info.avatar_url; + if (!info.inviter.empty()) + j["inviter"] = info.inviter; if (info.is_direct) j["is_direct"] = info.is_direct; if (!info.reason.empty()) @@ -5186,6 +5196,7 @@ from_json(const nlohmann::json &j, MemberInfo &info) info.avatar_url = j.value("avatar_url", ""); info.is_direct = j.value("is_direct", false); info.reason = j.value("reason", ""); + info.inviter = j.value("inviter", ""); } void diff --git a/src/CacheStructs.h b/src/CacheStructs.h index 6dad4b19..13c24c99 100644 --- a/src/CacheStructs.h +++ b/src/CacheStructs.h @@ -117,6 +117,7 @@ struct MemberInfo { std::string name; std::string avatar_url; + std::string inviter = ""; std::string reason = ""; bool is_direct = false; }; diff --git a/src/Cache_p.h b/src/Cache_p.h index f8716e81..121e7e66 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -394,8 +394,19 @@ private: auto display_name = e->content.display_name.empty() ? e->state_key : e->content.display_name; + std::string inviter = ""; + if (e->content.membership == mtx::events::state::Membership::Invite) { + inviter = e->sender; + } + // Lightweight representation of a member. - MemberInfo tmp{display_name, e->content.avatar_url, e->content.reason}; + MemberInfo tmp{ + display_name, + e->content.avatar_url, + inviter, + e->content.reason, + e->content.is_direct, + }; membersdb.put(txn, e->state_key, nlohmann::json(tmp).dump()); break; diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 35507cbd..ec41cc12 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -1235,3 +1235,49 @@ FilteredRoomlistModel::previousRoom() } } } + +QString +RoomPreview::inviterAvatarUrl() const +{ + if (isInvite_) { + auto self = cache::client()->getInviteMember(roomid_.toStdString(), + http::client()->user_id().to_string()); + if (self && !self->inviter.empty()) { + auto other = cache::client()->getInviteMember(roomid_.toStdString(), self->inviter); + if (other && other->avatar_url.starts_with("mxc://")) { + return QString::fromStdString(other->avatar_url); + } + } + } + + return QString(); +} +QString +RoomPreview::inviterDisplayName() const +{ + if (isInvite_) { + auto self = cache::client()->getInviteMember(roomid_.toStdString(), + http::client()->user_id().to_string()); + if (self && !self->inviter.empty()) { + auto other = cache::client()->getInviteMember(roomid_.toStdString(), self->inviter); + if (other) { + return QString::fromStdString(other->name).toHtmlEscaped(); + } + } + } + + return QString(); +} +QString +RoomPreview::inviterUserId() const +{ + if (isInvite_) { + auto self = cache::client()->getInviteMember(roomid_.toStdString(), + http::client()->user_id().to_string()); + if (self && !self->inviter.empty()) { + return QString::fromStdString(self->inviter); + } + } + + return QString(); +} diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index 9aaafc06..c06ab67d 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -31,6 +31,9 @@ class RoomPreview Q_PROPERTY(QString roomTopic READ roomTopic CONSTANT) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl CONSTANT) Q_PROPERTY(QString reason READ reason CONSTANT) + Q_PROPERTY(QString inviterAvatarUrl READ inviterAvatarUrl CONSTANT) + Q_PROPERTY(QString inviterDisplayName READ inviterDisplayName CONSTANT) + Q_PROPERTY(QString inviterUserId READ inviterUserId CONSTANT) Q_PROPERTY(bool isInvite READ isInvite CONSTANT) Q_PROPERTY(bool isFetched READ isFetched CONSTANT) @@ -42,6 +45,9 @@ public: QString roomTopic() const { return roomTopic_; } QString roomAvatarUrl() const { return roomAvatarUrl_; } QString reason() const { return reason_; } + QString inviterAvatarUrl() const; + QString inviterDisplayName() const; + QString inviterUserId() const; bool isInvite() const { return isInvite_; } bool isFetched() const { return isFetched_; } |