diff options
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | plugins/Matrix.hpp | 7 | ||||
-rw-r--r-- | src/plugins/Matrix.cpp | 61 |
3 files changed, 60 insertions, 12 deletions
@@ -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<RoomData> 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<CommandArg> additional_args, bool use_browser_useragent = false, std::string *err_msg = nullptr) const; private: std::vector<std::unique_ptr<RoomData>> rooms; std::unordered_map<std::string, size_t> 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<std::string, Invite> 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<CommandArg> 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<std::mutex> invite_lock(invite_mutex); + auto invite_it = invites.find(room_id); + if(invite_it != invites.end()) { + std::lock_guard<std::recursive_mutex> lock(room_data_mutex); + RoomData *room = get_room_by_id(room_id); + if(!room) { + auto new_room = std::make_unique<RoomData>(); + 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<std::string> &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<std::mutex> lock(room_data_mutex); + std::lock_guard<std::recursive_mutex> 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<RoomData> room) { - std::lock_guard<std::mutex> lock(room_data_mutex); + std::lock_guard<std::recursive_mutex> 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<std::mutex> lock(room_data_mutex); + std::lock_guard<std::recursive_mutex> 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<std::mutex> lock(invite_mutex); + invites[room_id] = std::move(invite); + } + + bool Matrix::remove_invite(const std::string &room_id) { + std::lock_guard<std::mutex> 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<CommandArg> 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? |