From 16ca6e63f4fd1b407c826a5574dc20b3f9e71675 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 3 Nov 2020 01:07:57 +0100 Subject: Matrix: sync with filter, lazy member fetch (reducing sync time from 35 sec with huge server to 3 seconds) and cached fetch to 150ms). Properly show notifications for older messages. Reduce memory usage from 120mb to 13mb --- plugins/Matrix.hpp | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'plugins') diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index 903215b..cde502d 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -99,7 +99,6 @@ namespace QuickMedia { // These 4 variables are set by QuickMedia, not the matrix plugin bool last_message_read = true; time_t last_read_message_timestamp = 0; - bool has_unread_mention = false; void *userdata = nullptr; // Pointer to BodyItem. Note: this has to be valid as long as the room is valid // These are messages fetched with |Matrix::get_message_by_id|. Needed to show replies, when replying to old message not part of /sync. @@ -110,10 +109,12 @@ namespace QuickMedia { size_t messages_read_index = 0; bool pinned_events_updated = false; - size_t index; + std::atomic_int unread_notification_count = 0; + + size_t index = 0; private: - std::mutex user_mutex; - std::mutex room_mutex; + std::recursive_mutex user_mutex; + std::recursive_mutex room_mutex; std::string name; std::string avatar_url; @@ -188,6 +189,8 @@ namespace QuickMedia { virtual void add_invite(const std::string &room_id, const Invite &invite) = 0; virtual void remove_invite(const std::string &room_id) = 0; + virtual void add_unread_notification(RoomData *room, std::string event_id, std::string sender, std::string body) = 0; + virtual void update(MatrixPageType page_type) { (void)page_type; } virtual void clear_data() = 0; @@ -212,6 +215,8 @@ namespace QuickMedia { void add_invite(const std::string &room_id, const Invite &invite) override; void remove_invite(const std::string &room_id) override; + void add_unread_notification(RoomData *room, std::string event_id, std::string sender, std::string body) override; + void update(MatrixPageType page_type) override; void clear_data() override; @@ -222,6 +227,7 @@ namespace QuickMedia { MatrixRoomTagsPage *room_tags_page; MatrixInvitesPage *invites_page; private: + void update_room_description(RoomData *room, bool is_initial_sync); void update_pending_room_messages(MatrixPageType page_type); private: struct RoomMessagesData { @@ -230,10 +236,18 @@ namespace QuickMedia { bool sync_is_cache; }; + struct Notification { + std::string event_id; + std::string sender; + std::string body; + }; + std::map> room_body_item_by_room; std::mutex room_body_items_mutex; std::map pending_room_messages; std::mutex pending_room_messages_mutex; + + std::unordered_map> unread_notifications; }; class MatrixRoomsPage : public Page { @@ -253,6 +267,7 @@ namespace QuickMedia { void set_current_chat_page(MatrixChatPage *chat_page); void clear_data(); + void sort_rooms(); MatrixQuickMedia *matrix_delegate = nullptr; private: @@ -264,6 +279,7 @@ namespace QuickMedia { MatrixRoomTagsPage *room_tags_page = nullptr; MatrixChatPage *current_chat_page = nullptr; bool clear_data_on_update = false; + bool sort_on_update = false; }; class MatrixRoomTagsPage : public Page { @@ -282,6 +298,7 @@ namespace QuickMedia { void set_current_rooms_page(MatrixRoomsPage *rooms_page); void clear_data(); + void sort_rooms(); MatrixQuickMedia *matrix_delegate = nullptr; private: @@ -425,18 +442,20 @@ namespace QuickMedia { bool use_tor = false; private: - PluginResult parse_sync_response(const rapidjson::Document &root, MatrixDelegate *delegate); + PluginResult parse_sync_response(const rapidjson::Document &root); + PluginResult parse_notifications(const rapidjson::Value ¬ifications_json); PluginResult parse_sync_account_data(const rapidjson::Value &account_data_json, std::optional> &dm_rooms); - PluginResult parse_sync_room_data(const rapidjson::Value &rooms_json, MatrixDelegate *delegate); + PluginResult parse_sync_room_data(const rapidjson::Value &rooms_json); PluginResult get_previous_room_messages(RoomData *room_data); void events_add_user_info(const rapidjson::Value &events_json, RoomData *room_data); void events_add_user_read_markers(const rapidjson::Value &events_json, RoomData *room_data); - void events_add_messages(const rapidjson::Value &events_json, RoomData *room_data, MessageDirection message_dir, MatrixDelegate *delegate, bool has_unread_notifications); + void events_set_user_read_marker(const rapidjson::Value &events_json, RoomData *room_data, std::shared_ptr &me); + void events_add_messages(const rapidjson::Value &events_json, RoomData *room_data, MessageDirection message_dir, bool has_unread_notifications); void events_set_room_name(const rapidjson::Value &events_json, RoomData *room_data); void events_add_pinned_events(const rapidjson::Value &events_json, RoomData *room_data); - void events_add_room_to_tags(const rapidjson::Value &events_json, RoomData *room_data, MatrixDelegate *delegate); - void add_invites(const rapidjson::Value &invite_json, MatrixDelegate *delegate); - void remove_rooms(const rapidjson::Value &leave_json, MatrixDelegate *delegate); + void events_add_room_to_tags(const rapidjson::Value &events_json, RoomData *room_data); + void add_invites(const rapidjson::Value &invite_json); + void remove_rooms(const rapidjson::Value &leave_json); std::shared_ptr parse_message_event(const rapidjson::Value &event_item_json, RoomData *room_data); PluginResult upload_file(RoomData *room, const std::string &filepath, UploadInfo &file_info, UploadInfo &thumbnail_info, std::string &err_msg); void add_room(std::unique_ptr room); @@ -463,6 +482,7 @@ namespace QuickMedia { std::mutex invite_mutex; std::thread sync_thread; + std::thread notification_thread; bool sync_running = false; bool sync_failed = false; bool sync_is_cache = false; -- cgit v1.2.3