Show invite reason in the UI (hidden by default)

pull/1253/head
Nicolas Werner 2 years ago
parent c0b7963134
commit f98b289ba2
No known key found for this signature in database
GPG Key ID: C8D75E610773F2D9
  1. 2
      CMakeLists.txt
  2. 2
      io.github.NhekoReborn.Nheko.yaml
  3. 39
      resources/qml/TimelineView.qml
  4. 29
      src/Cache.cpp
  5. 1
      src/CacheStructs.h
  6. 8
      src/Cache_p.h
  7. 14
      src/timeline/RoomlistModel.cpp
  8. 4
      src/timeline/RoomlistModel.h

@ -595,7 +595,7 @@ if(USE_BUNDLED_MTXCLIENT)
FetchContent_Declare( FetchContent_Declare(
MatrixClient MatrixClient
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
GIT_TAG 6252a4a902053fb227b61e65e76c1c29bc905a45 GIT_TAG d187c63a27710fa87a44ab44d43b7cfa2023132a
) )
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")

@ -182,7 +182,7 @@ modules:
buildsystem: cmake-ninja buildsystem: cmake-ninja
name: mtxclient name: mtxclient
sources: sources:
- commit: 6252a4a902053fb227b61e65e76c1c29bc905a45 - commit: d187c63a27710fa87a44ab44d43b7cfa2023132a
#tag: v0.8.2 #tag: v0.8.2
type: git type: git
url: https://github.com/Nheko-Reborn/mtxclient.git url: https://github.com/Nheko-Reborn/mtxclient.git

@ -170,6 +170,7 @@ Item {
property string roomName: room ? room.roomName : (roomPreview ? roomPreview.roomName : "") property string roomName: room ? room.roomName : (roomPreview ? roomPreview.roomName : "")
property string roomTopic: room ? room.roomTopic : (roomPreview ? roomPreview.roomTopic : "") property string roomTopic: room ? room.roomTopic : (roomPreview ? roomPreview.roomTopic : "")
property string avatarUrl: room ? room.roomAvatarUrl : (roomPreview ? roomPreview.roomAvatarUrl : "") property string avatarUrl: room ? room.roomAvatarUrl : (roomPreview ? roomPreview.roomAvatarUrl : "")
property string reason: roomPreview ? roomPreview.reason : ""
visible: room != null && room.isSpace || roomPreview != null visible: room != null && room.isSpace || roomPreview != null
enabled: visible enabled: visible
@ -277,6 +278,44 @@ Item {
onClicked: Rooms.declineInvite(roomPreview.roomid) onClicked: Rooms.declineInvite(roomPreview.roomid)
} }
ScrollView {
id: reasonField
property bool showReason: false
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: Nheko.paddingLarge
Layout.rightMargin: Nheko.paddingLarge
visible: preview.reason !== "" && showReason
TextArea {
text: TimelineManager.escapeEmoji(preview.reason)
wrapMode: TextEdit.WordWrap
textFormat: TextEdit.RichText
readOnly: true
background: null
selectByMouse: true
color: Nheko.colors.text
horizontalAlignment: TextEdit.AlignHCenter
}
}
Button {
id: showReasonButton
Layout.alignment: Qt.AlignHCenter
//Layout.fillWidth: true
Layout.leftMargin: Nheko.paddingLarge
Layout.rightMargin: Nheko.paddingLarge
visible: preview.reason !== ""
text: reasonField.showReason ? qsTr("Hide invite reason") : qsTr("Show invite reason")
onClicked: {
reasonField.showReason = !reasonField.showReason;
}
}
Item { Item {
visible: room != null visible: room != null
Layout.preferredHeight: Math.ceil(fontMetrics.lineSpacing * 2) Layout.preferredHeight: Math.ceil(fontMetrics.lineSpacing * 2)

@ -2018,7 +2018,8 @@ Cache::saveInvite(lmdb::txn &txn,
auto display_name = auto display_name =
msg->content.display_name.empty() ? msg->state_key : msg->content.display_name; msg->content.display_name.empty() ? msg->state_key : msg->content.display_name;
MemberInfo tmp{display_name, msg->content.avatar_url, msg->content.is_direct}; MemberInfo tmp{
display_name, msg->content.avatar_url, msg->content.reason, msg->content.is_direct};
membersdb.put(txn, msg->state_key, nlohmann::json(tmp).dump()); membersdb.put(txn, msg->state_key, nlohmann::json(tmp).dump());
} else { } else {
@ -3144,6 +3145,29 @@ Cache::getMembers(const std::string &room_id, std::size_t startIndex, std::size_
} }
} }
std::optional<MemberInfo>
Cache::getInviteMember(const std::string &room_id, const std::string &user_id)
{
if (user_id.empty() || !env_.handle())
return std::nullopt;
try {
auto txn = ro_txn(env_);
auto membersdb = getInviteMembersDb(txn, room_id);
std::string_view info;
if (membersdb.get(txn, user_id, info)) {
MemberInfo m = nlohmann::json::parse(info).get<MemberInfo>();
return m;
}
} catch (std::exception &e) {
nhlog::db()->warn(
"Failed to read member ({}) in invite room ({}): {}", user_id, room_id, e.what());
}
return std::nullopt;
}
std::vector<RoomMember> std::vector<RoomMember>
Cache::getMembersFromInvite(const std::string &room_id, std::size_t startIndex, std::size_t len) Cache::getMembersFromInvite(const std::string &room_id, std::size_t startIndex, std::size_t len)
{ {
@ -4959,6 +4983,8 @@ to_json(nlohmann::json &j, const MemberInfo &info)
j["avatar_url"] = info.avatar_url; j["avatar_url"] = info.avatar_url;
if (info.is_direct) if (info.is_direct)
j["is_direct"] = info.is_direct; j["is_direct"] = info.is_direct;
if (!info.reason.empty())
j["reason"] = info.reason;
} }
void void
@ -4967,6 +4993,7 @@ from_json(const nlohmann::json &j, MemberInfo &info)
info.name = j.at("name").get<std::string>(); info.name = j.at("name").get<std::string>();
info.avatar_url = j.at("avatar_url").get<std::string>(); info.avatar_url = j.at("avatar_url").get<std::string>();
info.is_direct = j.value("is_direct", false); info.is_direct = j.value("is_direct", false);
info.reason = j.value("reason", "");
} }
void void

@ -107,6 +107,7 @@ struct MemberInfo
{ {
std::string name; std::string name;
std::string avatar_url; std::string avatar_url;
std::string reason;
bool is_direct = false; bool is_direct = false;
}; };

@ -244,6 +244,8 @@ public:
//! Check if a user is a member of the room. //! Check if a user is a member of the room.
bool isRoomMember(const std::string &user_id, const std::string &room_id); bool isRoomMember(const std::string &user_id, const std::string &room_id);
std::optional<MemberInfo>
getInviteMember(const std::string &room_id, const std::string &user_id);
// //
// Outbound Megolm Sessions // Outbound Megolm Sessions
@ -396,7 +398,7 @@ private:
e->content.display_name.empty() ? e->state_key : e->content.display_name; e->content.display_name.empty() ? e->state_key : e->content.display_name;
// Lightweight representation of a member. // Lightweight representation of a member.
MemberInfo tmp{display_name, e->content.avatar_url}; MemberInfo tmp{display_name, e->content.avatar_url, e->content.reason};
membersdb.put(txn, e->state_key, nlohmann::json(tmp).dump()); membersdb.put(txn, e->state_key, nlohmann::json(tmp).dump());
break; break;
@ -406,8 +408,8 @@ private:
break; break;
} }
} }
// fallthrough to also store it as state event to eventually migrate away from a
return; // separate members db.
} else if (std::holds_alternative<StateEvent<Encryption>>(event)) { } else if (std::holds_alternative<StateEvent<Encryption>>(event)) {
setEncryptedRoom(txn, room_id); setEncryptedRoom(txn, room_id);
return; return;

@ -723,6 +723,13 @@ RoomlistModel::getRoomPreviewById(QString roomid) const
if (invites.contains(roomid)) { if (invites.contains(roomid)) {
i = invites.value(roomid); i = invites.value(roomid);
preview.isInvite_ = true; preview.isInvite_ = true;
auto member = cache::client()->getInviteMember(roomid.toStdString(),
http::client()->user_id().to_string());
if (member) {
preview.reason_ = QString::fromStdString(member->reason);
}
} else { } else {
i = previewedRooms.value(roomid); i = previewedRooms.value(roomid);
preview.isInvite_ = false; preview.isInvite_ = false;
@ -769,6 +776,13 @@ RoomlistModel::setCurrentRoom(const QString &roomid)
if (invites.contains(roomid)) { if (invites.contains(roomid)) {
i = invites.value(roomid); i = invites.value(roomid);
p.isInvite_ = true; p.isInvite_ = true;
auto member = cache::client()->getInviteMember(roomid.toStdString(),
http::client()->user_id().to_string());
if (member) {
p.reason_ = QString::fromStdString(member->reason);
}
} else { } else {
i = previewedRooms.value(roomid); i = previewedRooms.value(roomid);
p.isInvite_ = false; p.isInvite_ = false;

@ -31,6 +31,7 @@ class RoomPreview
Q_PROPERTY(QString roomName READ roomName CONSTANT) Q_PROPERTY(QString roomName READ roomName CONSTANT)
Q_PROPERTY(QString roomTopic READ roomTopic CONSTANT) Q_PROPERTY(QString roomTopic READ roomTopic CONSTANT)
Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl CONSTANT) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl CONSTANT)
Q_PROPERTY(QString reason READ reason CONSTANT)
Q_PROPERTY(bool isInvite READ isInvite CONSTANT) Q_PROPERTY(bool isInvite READ isInvite CONSTANT)
public: public:
@ -40,9 +41,10 @@ public:
QString roomName() const { return roomName_; } QString roomName() const { return roomName_; }
QString roomTopic() const { return roomTopic_; } QString roomTopic() const { return roomTopic_; }
QString roomAvatarUrl() const { return roomAvatarUrl_; } QString roomAvatarUrl() const { return roomAvatarUrl_; }
QString reason() const { return reason_; }
bool isInvite() const { return isInvite_; } bool isInvite() const { return isInvite_; }
QString roomid_, roomName_, roomAvatarUrl_, roomTopic_; QString roomid_, roomName_, roomAvatarUrl_, roomTopic_, reason_;
bool isInvite_ = false; bool isInvite_ = false;
}; };

Loading…
Cancel
Save