diff --git a/src/Cache.cpp b/src/Cache.cpp index d3aec9db..e61d101e 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -78,6 +78,13 @@ constexpr auto OUTBOUND_MEGOLM_SESSIONS_DB("outbound_megolm_sessions"); using CachedReceipts = std::multimap>; using Receipts = std::map>; +Q_DECLARE_METATYPE(SearchResult) +Q_DECLARE_METATYPE(QVector) +Q_DECLARE_METATYPE(RoomMember) +Q_DECLARE_METATYPE(mtx::responses::Timeline) +Q_DECLARE_METATYPE(RoomSearchResult) +Q_DECLARE_METATYPE(RoomInfo) + namespace { std::unique_ptr instance_ = nullptr; } @@ -1504,7 +1511,7 @@ Cache::getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb) return "Empty Room"; } -JoinRule +mtx::events::state::JoinRule Cache::getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb) { using namespace mtx::events; @@ -1516,14 +1523,14 @@ Cache::getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb) if (res) { try { - StateEvent msg = + StateEvent msg = json::parse(std::string(event.data(), event.size())); return msg.content.join_rule; } catch (const json::exception &e) { nhlog::db()->warn("failed to parse m.room.join_rule event: {}", e.what()); } } - return JoinRule::Knock; + return state::JoinRule::Knock; } bool @@ -2313,3 +2320,91 @@ from_json(const json &j, RoomInfo &info) if (j.count("tags")) info.tags = j.at("tags").get>(); } + +int +numeric_key_comparison(const MDB_val *a, const MDB_val *b) +{ + auto lhs = std::stoull(std::string((char *)a->mv_data, a->mv_size)); + auto rhs = std::stoull(std::string((char *)b->mv_data, b->mv_size)); + + if (lhs < rhs) + return 1; + else if (lhs == rhs) + return 0; + + return -1; +} + +void +to_json(json &j, const ReadReceiptKey &key) +{ + j = json{{"event_id", key.event_id}, {"room_id", key.room_id}}; +} + +void +from_json(const json &j, ReadReceiptKey &key) +{ + key.event_id = j.at("event_id").get(); + key.room_id = j.at("room_id").get(); +} + +void +to_json(json &j, const MemberInfo &info) +{ + j["name"] = info.name; + j["avatar_url"] = info.avatar_url; +} + +void +from_json(const json &j, MemberInfo &info) +{ + info.name = j.at("name"); + info.avatar_url = j.at("avatar_url"); +} + +void +to_json(nlohmann::json &obj, const OutboundGroupSessionData &msg) +{ + obj["session_id"] = msg.session_id; + obj["session_key"] = msg.session_key; + obj["message_index"] = msg.message_index; +} + +void +from_json(const nlohmann::json &obj, OutboundGroupSessionData &msg) +{ + msg.session_id = obj.at("session_id"); + msg.session_key = obj.at("session_key"); + msg.message_index = obj.at("message_index"); +} + +void +to_json(nlohmann::json &obj, const DevicePublicKeys &msg) +{ + obj["ed25519"] = msg.ed25519; + obj["curve25519"] = msg.curve25519; +} + +void +from_json(const nlohmann::json &obj, DevicePublicKeys &msg) +{ + msg.ed25519 = obj.at("ed25519"); + msg.curve25519 = obj.at("curve25519"); +} + +void +to_json(nlohmann::json &obj, const MegolmSessionIndex &msg) +{ + obj["room_id"] = msg.room_id; + obj["session_id"] = msg.session_id; + obj["sender_key"] = msg.sender_key; +} + +void +from_json(const nlohmann::json &obj, MegolmSessionIndex &msg) +{ + msg.room_id = obj.at("room_id"); + msg.session_id = obj.at("session_id"); + msg.sender_key = obj.at("sender_key"); +} + diff --git a/src/Cache.h b/src/Cache.h index 878ac9ce..02346287 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -28,224 +28,16 @@ #include #include -#include #include #include +#include "CacheCryptoStructs.h" +#include "CacheStructs.h" #include "Logging.h" #include "MatrixClient.h" -using mtx::events::state::JoinRule; - -struct RoomMember -{ - QString user_id; - QString display_name; - QImage avatar; -}; - -struct SearchResult -{ - QString user_id; - QString display_name; -}; - -static int -numeric_key_comparison(const MDB_val *a, const MDB_val *b) -{ - auto lhs = std::stoull(std::string((char *)a->mv_data, a->mv_size)); - auto rhs = std::stoull(std::string((char *)b->mv_data, b->mv_size)); - - if (lhs < rhs) - return 1; - else if (lhs == rhs) - return 0; - - return -1; -} - -Q_DECLARE_METATYPE(SearchResult) -Q_DECLARE_METATYPE(QVector) -Q_DECLARE_METATYPE(RoomMember) -Q_DECLARE_METATYPE(mtx::responses::Timeline) - -//! Used to uniquely identify a list of read receipts. -struct ReadReceiptKey -{ - std::string event_id; - std::string room_id; -}; - -inline void -to_json(json &j, const ReadReceiptKey &key) -{ - j = json{{"event_id", key.event_id}, {"room_id", key.room_id}}; -} - -inline void -from_json(const json &j, ReadReceiptKey &key) -{ - key.event_id = j.at("event_id").get(); - key.room_id = j.at("room_id").get(); -} - -struct DescInfo -{ - QString event_id; - QString userid; - QString body; - QString timestamp; - QDateTime datetime; -}; - -//! UI info associated with a room. -struct RoomInfo -{ - //! The calculated name of the room. - std::string name; - //! The topic of the room. - std::string topic; - //! The calculated avatar url of the room. - std::string avatar_url; - //! The calculated version of this room set at creation time. - std::string version; - //! Whether or not the room is an invite. - bool is_invite = false; - //! Total number of members in the room. - int16_t member_count = 0; - //! Who can access to the room. - JoinRule join_rule = JoinRule::Public; - bool guest_access = false; - //! Metadata describing the last message in the timeline. - DescInfo msgInfo; - //! The list of tags associated with this room - std::vector tags; -}; - -void -to_json(json &j, const RoomInfo &info); - -void -from_json(const json &j, RoomInfo &info); - -//! Basic information per member; -struct MemberInfo -{ - std::string name; - std::string avatar_url; -}; - -inline void -to_json(json &j, const MemberInfo &info) -{ - j["name"] = info.name; - j["avatar_url"] = info.avatar_url; -} - -inline void -from_json(const json &j, MemberInfo &info) -{ - info.name = j.at("name"); - info.avatar_url = j.at("avatar_url"); -} - -struct RoomSearchResult -{ - std::string room_id; - RoomInfo info; -}; - -Q_DECLARE_METATYPE(RoomSearchResult) -Q_DECLARE_METATYPE(RoomInfo) - -// Extra information associated with an outbound megolm session. -struct OutboundGroupSessionData -{ - std::string session_id; - std::string session_key; - uint64_t message_index = 0; -}; - -inline void -to_json(nlohmann::json &obj, const OutboundGroupSessionData &msg) -{ - obj["session_id"] = msg.session_id; - obj["session_key"] = msg.session_key; - obj["message_index"] = msg.message_index; -} - -inline void -from_json(const nlohmann::json &obj, OutboundGroupSessionData &msg) -{ - msg.session_id = obj.at("session_id"); - msg.session_key = obj.at("session_key"); - msg.message_index = obj.at("message_index"); -} - -struct OutboundGroupSessionDataRef -{ - OlmOutboundGroupSession *session; - OutboundGroupSessionData data; -}; - -struct DevicePublicKeys -{ - std::string ed25519; - std::string curve25519; -}; - -inline void -to_json(nlohmann::json &obj, const DevicePublicKeys &msg) -{ - obj["ed25519"] = msg.ed25519; - obj["curve25519"] = msg.curve25519; -} - -inline void -from_json(const nlohmann::json &obj, DevicePublicKeys &msg) -{ - msg.ed25519 = obj.at("ed25519"); - msg.curve25519 = obj.at("curve25519"); -} - -//! Represents a unique megolm session identifier. -struct MegolmSessionIndex -{ - //! The room in which this session exists. - std::string room_id; - //! The session_id of the megolm session. - std::string session_id; - //! The curve25519 public key of the sender. - std::string sender_key; -}; - -inline void -to_json(nlohmann::json &obj, const MegolmSessionIndex &msg) -{ - obj["room_id"] = msg.room_id; - obj["session_id"] = msg.session_id; - obj["sender_key"] = msg.sender_key; -} - -inline void -from_json(const nlohmann::json &obj, MegolmSessionIndex &msg) -{ - msg.room_id = obj.at("room_id"); - msg.session_id = obj.at("session_id"); - msg.sender_key = obj.at("sender_key"); -} - -struct OlmSessionStorage -{ - // Megolm sessions - std::map group_inbound_sessions; - std::map group_outbound_sessions; - std::map group_outbound_session_data; - - // Guards for accessing megolm sessions. - std::mutex group_outbound_mtx; - std::mutex group_inbound_mtx; -}; +int +numeric_key_comparison(const MDB_val *a, const MDB_val *b); class Cache : public QObject { @@ -287,7 +79,7 @@ public: //! Calculate & return the name of the room. QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); //! Get room join rules - JoinRule getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb); + mtx::events::state::JoinRule getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb); bool getRoomGuestAccess(lmdb::txn &txn, lmdb::dbi &statesdb); //! Retrieve the topic of the room if any. QString getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); diff --git a/src/CacheCryptoStructs.h b/src/CacheCryptoStructs.h new file mode 100644 index 00000000..14c9c86b --- /dev/null +++ b/src/CacheCryptoStructs.h @@ -0,0 +1,67 @@ +#pragma once + +#include +#include + +//#include + +#include +#include + +// Extra information associated with an outbound megolm session. +struct OutboundGroupSessionData +{ + std::string session_id; + std::string session_key; + uint64_t message_index = 0; +}; + +void +to_json(nlohmann::json &obj, const OutboundGroupSessionData &msg); +void +from_json(const nlohmann::json &obj, OutboundGroupSessionData &msg); + +struct OutboundGroupSessionDataRef +{ + OlmOutboundGroupSession *session; + OutboundGroupSessionData data; +}; + +struct DevicePublicKeys +{ + std::string ed25519; + std::string curve25519; +}; + +void +to_json(nlohmann::json &obj, const DevicePublicKeys &msg); +void +from_json(const nlohmann::json &obj, DevicePublicKeys &msg); + +//! Represents a unique megolm session identifier. +struct MegolmSessionIndex +{ + //! The room in which this session exists. + std::string room_id; + //! The session_id of the megolm session. + std::string session_id; + //! The curve25519 public key of the sender. + std::string sender_key; +}; + +void +to_json(nlohmann::json &obj, const MegolmSessionIndex &msg); +void +from_json(const nlohmann::json &obj, MegolmSessionIndex &msg); + +struct OlmSessionStorage +{ + // Megolm sessions + std::map group_inbound_sessions; + std::map group_outbound_sessions; + std::map group_outbound_session_data; + + // Guards for accessing megolm sessions. + std::mutex group_outbound_mtx; + std::mutex group_inbound_mtx; +}; diff --git a/src/CacheStructs.h b/src/CacheStructs.h new file mode 100644 index 00000000..275d20cb --- /dev/null +++ b/src/CacheStructs.h @@ -0,0 +1,91 @@ +#pragma once + +#include +#include +#include + +#include + +#include + +struct RoomMember +{ + QString user_id; + QString display_name; + QImage avatar; +}; + +struct SearchResult +{ + QString user_id; + QString display_name; +}; + +//! Used to uniquely identify a list of read receipts. +struct ReadReceiptKey +{ + std::string event_id; + std::string room_id; +}; + +void +to_json(json &j, const ReadReceiptKey &key); + +void +from_json(const json &j, ReadReceiptKey &key); + +struct DescInfo +{ + QString event_id; + QString userid; + QString body; + QString timestamp; + QDateTime datetime; +}; + +//! UI info associated with a room. +struct RoomInfo +{ + //! The calculated name of the room. + std::string name; + //! The topic of the room. + std::string topic; + //! The calculated avatar url of the room. + std::string avatar_url; + //! The calculated version of this room set at creation time. + std::string version; + //! Whether or not the room is an invite. + bool is_invite = false; + //! Total number of members in the room. + int16_t member_count = 0; + //! Who can access to the room. + mtx::events::state::JoinRule join_rule = mtx::events::state::JoinRule::Public; + bool guest_access = false; + //! Metadata describing the last message in the timeline. + DescInfo msgInfo; + //! The list of tags associated with this room + std::vector tags; +}; + +void +to_json(json &j, const RoomInfo &info); +void +from_json(const json &j, RoomInfo &info); + +//! Basic information per member; +struct MemberInfo +{ + std::string name; + std::string avatar_url; +}; + +void +to_json(json &j, const MemberInfo &info); +void +from_json(const json &j, MemberInfo &info); + +struct RoomSearchResult +{ + std::string room_id; + RoomInfo info; +}; diff --git a/src/ChatPage.h b/src/ChatPage.h index 6ca30b3d..6337f800 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -32,7 +32,7 @@ #include #include -#include "Cache.h" +#include "CacheStructs.h" #include "CommunitiesList.h" #include "MatrixClient.h" #include "Utils.h" diff --git a/src/CommunitiesList.h b/src/CommunitiesList.h index b18df654..fbb63ff0 100644 --- a/src/CommunitiesList.h +++ b/src/CommunitiesList.h @@ -4,7 +4,7 @@ #include #include -#include "Cache.h" +#include "CacheStructs.h" #include "CommunitiesListItem.h" #include "ui/Theme.h" @@ -53,3 +53,4 @@ private: std::map> communities_; }; + diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp index 1e06d914..926e1359 100644 --- a/src/RoomInfoListItem.cpp +++ b/src/RoomInfoListItem.cpp @@ -97,7 +97,7 @@ RoomInfoListItem::init(QWidget *parent) menu_->addAction(leaveRoom_); } -RoomInfoListItem::RoomInfoListItem(QString room_id, RoomInfo info, QWidget *parent) +RoomInfoListItem::RoomInfoListItem(QString room_id, const RoomInfo &info, QWidget *parent) : QWidget(parent) , roomType_{info.is_invite ? RoomType::Invited : RoomType::Joined} , roomId_(std::move(room_id)) diff --git a/src/RoomInfoListItem.h b/src/RoomInfoListItem.h index 54e02a76..16553c73 100644 --- a/src/RoomInfoListItem.h +++ b/src/RoomInfoListItem.h @@ -22,9 +22,10 @@ #include #include -#include "Cache.h" #include +#include "CacheStructs.h" + class Menu; class RippleOverlay; @@ -64,7 +65,7 @@ class RoomInfoListItem : public QWidget Q_PROPERTY(QColor btnTextColor READ btnTextColor WRITE setBtnTextColor) public: - RoomInfoListItem(QString room_id, RoomInfo info, QWidget *parent = 0); + RoomInfoListItem(QString room_id, const RoomInfo &info, QWidget *parent = 0); void updateUnreadMessageCount(int count, int highlightedCount); void clearUnreadMessageCount() { updateUnreadMessageCount(0, 0); }; diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp index 25909cd8..1be33d33 100644 --- a/src/dialogs/RoomSettings.cpp +++ b/src/dialogs/RoomSettings.cpp @@ -248,10 +248,10 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent) switch (index) { case 0: case 1: - event.join_rule = JoinRule::Public; + event.join_rule = state::JoinRule::Public; break; default: - event.join_rule = JoinRule::Invite; + event.join_rule = state::JoinRule::Invite; } return event; @@ -260,7 +260,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent) updateAccessRules(room_id_.toStdString(), join_rule, guest_access); }); - if (info_.join_rule == JoinRule::Public) { + if (info_.join_rule == state::JoinRule::Public) { if (info_.guest_access) { accessCombo->setCurrentIndex(0); } else { @@ -342,7 +342,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent) } // Hide encryption option for public rooms. - if (!usesEncryption_ && (info_.join_rule == JoinRule::Public)) { + if (!usesEncryption_ && (info_.join_rule == state::JoinRule::Public)) { encryptionToggle_->hide(); encryptionLabel->hide(); diff --git a/src/popups/SuggestionsPopup.h b/src/popups/SuggestionsPopup.h index 1ef720b2..536c82fb 100644 --- a/src/popups/SuggestionsPopup.h +++ b/src/popups/SuggestionsPopup.h @@ -10,6 +10,8 @@ #include "../ChatPage.h" #include "PopupItem.h" +Q_DECLARE_METATYPE(QVector) + class SuggestionsPopup : public QWidget { Q_OBJECT diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 05e05962..5391c7c1 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -9,7 +9,7 @@ #include #include -#include "Cache.h" +#include "CacheCryptoStructs.h" #include "Logging.h" #include "MatrixClient.h"