From 13935702620305c5baaf6403417cc75a9b706fea Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 1 Nov 2020 13:24:16 +0100 Subject: Matrix: create room immediately after receiving join response, instead of waiting for join sync message --- TODO | 4 +++- plugins/Matrix.hpp | 7 +++++- src/plugins/Matrix.cpp | 61 +++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index cb6624e..29f426c 100644 --- a/TODO +++ b/TODO @@ -130,4 +130,6 @@ Show marker beside pinned messages tab name if there are new pinned messages. Make /logout work everywhere, not only in room message input. Add a notifications tab to show messages that mention us in all rooms (and then press enter to go to that message in that room). Disable message input in matrix when muted. -Preview rooms? \ No newline at end of file +Preview rooms? +Instantly show messages posted by me until we receive our message from the server (use post response which includes event id). +Get user displayname, avatar, room name, etc updates from /sync and update them in gui. \ No newline at end of file diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index 3d3c4b2..6a876d0 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -423,11 +423,14 @@ namespace QuickMedia { 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); void remove_room(const std::string &room_id); + void set_invite(const std::string &room_id, Invite invite); + // Returns true if an invite for |room_id| exists + bool remove_invite(const std::string &room_id); DownloadResult download_json(rapidjson::Document &result, const std::string &url, std::vector additional_args, bool use_browser_useragent = false, std::string *err_msg = nullptr) const; private: std::vector> rooms; std::unordered_map room_data_by_id; // value is an index into |rooms| - std::mutex room_data_mutex; + std::recursive_mutex room_data_mutex; std::string user_id; std::string username; std::string access_token; @@ -436,8 +439,10 @@ namespace QuickMedia { std::string next_batch; std::unordered_map invites; + std::mutex invite_mutex; std::thread sync_thread; bool sync_running = false; + MatrixDelegate *delegate = nullptr; }; } \ No newline at end of file diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index b8c2f89..d143e9a 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -641,6 +641,9 @@ namespace QuickMedia { if(sync_running) return; + assert(!this->delegate); + this->delegate = delegate; + sync_running = true; sync_thread = std::thread([this, delegate]() { const rapidjson::Value *next_batch_json; @@ -690,6 +693,7 @@ namespace QuickMedia { program_kill_in_thread(sync_thread.get_id()); if(sync_thread.joinable()) sync_thread.join(); + delegate = nullptr; } bool Matrix::is_initial_sync_finished() const { @@ -871,11 +875,9 @@ namespace QuickMedia { } } - auto invites_it = invites.find(room_id_str); - if(invites_it != invites.end()) { + if(remove_invite(room_id_str)) { // TODO: Show leave type and reason and who caused the invite to be removed delegate->remove_invite(room_id_str); - invites.erase(invites_it); } if(is_new_room) @@ -1597,7 +1599,7 @@ namespace QuickMedia { std::string room_id_str(room_id.GetString(), room_id.GetStringLength()); delegate->add_invite(room_id_str, invite); - invites[room_id_str] = std::move(invite); + set_invite(room_id_str, std::move(invite)); break; } } @@ -1617,11 +1619,9 @@ namespace QuickMedia { continue; std::string room_id_str(room_id.GetString(), room_id.GetStringLength()); - auto invites_it = invites.find(room_id_str); - if(invites_it != invites.end()) { + if(remove_invite(room_id_str)) { // TODO: Show leave type and reason and who caused the invite to be removed delegate->remove_invite(room_id_str); - invites.erase(invites_it); } const rapidjson::Value &timeline_json = GetMember(it.value, "timeline"); @@ -2532,6 +2532,7 @@ namespace QuickMedia { } PluginResult Matrix::join_room(const std::string &room_id) { + assert(delegate); std::vector additional_args = { { "-X", "POST" }, { "-H", "content-type: application/json" }, @@ -2541,6 +2542,31 @@ namespace QuickMedia { std::string server_response; DownloadResult download_result = download_to_string(homeserver + "/_matrix/client/r0/join/" + room_id, server_response, std::move(additional_args), use_tor, true); + if(download_result == DownloadResult::OK) { + std::lock_guard invite_lock(invite_mutex); + auto invite_it = invites.find(room_id); + if(invite_it != invites.end()) { + std::lock_guard lock(room_data_mutex); + RoomData *room = get_room_by_id(room_id); + if(!room) { + auto new_room = std::make_unique(); + new_room->id = room_id; + new_room->set_name(invite_it->second.room_name); + new_room->set_avatar_url(invite_it->second.room_avatar_url); + room = new_room.get(); + add_room(std::move(new_room)); + + delegate->join_room(room); + room->acquire_room_lock(); + std::set &room_tags = room->get_tags_unsafe(); + if(room_tags.empty()) { + room_tags.insert(OTHERS_ROOM_TAG); + delegate->room_add_tag(room, OTHERS_ROOM_TAG); + } + room->release_room_lock(); + } + } + } return download_result_to_plugin_result(download_result); } @@ -2604,7 +2630,7 @@ namespace QuickMedia { } RoomData* Matrix::get_room_by_id(const std::string &id) { - std::lock_guard lock(room_data_mutex); + std::lock_guard lock(room_data_mutex); auto room_it = room_data_by_id.find(id); if(room_it == room_data_by_id.end()) return nullptr; @@ -2612,14 +2638,14 @@ namespace QuickMedia { } void Matrix::add_room(std::unique_ptr room) { - std::lock_guard lock(room_data_mutex); + std::lock_guard lock(room_data_mutex); room->index = rooms.size(); room_data_by_id.insert(std::make_pair(room->id, room->index)); rooms.push_back(std::move(room)); } void Matrix::remove_room(const std::string &room_id) { - std::lock_guard lock(room_data_mutex); + std::lock_guard lock(room_data_mutex); auto room_it = room_data_by_id.find(room_id); if(room_it == room_data_by_id.end()) return; @@ -2630,6 +2656,21 @@ namespace QuickMedia { room_data_by_id.erase(room_it); } + void Matrix::set_invite(const std::string &room_id, Invite invite) { + std::lock_guard lock(invite_mutex); + invites[room_id] = std::move(invite); + } + + bool Matrix::remove_invite(const std::string &room_id) { + std::lock_guard lock(invite_mutex); + auto invites_it = invites.find(room_id); + if(invites_it != invites.end()) { + invites.erase(invites_it); + return true; + } + return false; + } + DownloadResult Matrix::download_json(rapidjson::Document &result, const std::string &url, std::vector additional_args, bool use_browser_useragent, std::string *err_msg) const { if(download_to_json(url, result, std::move(additional_args), use_tor, use_browser_useragent, err_msg == nullptr) != DownloadResult::OK) { // Cant get error since we parse directory to json. TODO: Make this work somehow? -- cgit v1.2.3