From 37e0de2d586099fba5736b13dfb945db5f54fe94 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 17 Aug 2021 14:27:27 +0200 Subject: Matrix: fix room description not including message on initial sync because of pinned events --- src/plugins/Matrix.cpp | 75 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 22 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 5139380..35442ed 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -32,7 +32,7 @@ namespace QuickMedia { // Filter without account data. TODO: We include pinned events but limit events to 1. That means if the last event is a pin, // then we cant see room message preview. TODO: Fix this somehow. // TODO: What about state events in initial sync in timeline? such as user display name change. - static const char* INITIAL_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"types\":[\"m.room.message\",\"m.room.pinned_events\"],\"limit\":1,\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"limit\":1,\"types\":[\"m.fully_read\",\"m.tag\",\"qm.last_read_message_timestamp\"],\"lazy_load_members\":true}}}"; + static const char* INITIAL_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"types\":[\"m.room.message\"],\"limit\":1,\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"limit\":1,\"types\":[\"m.fully_read\",\"m.tag\",\"qm.last_read_message_timestamp\"],\"lazy_load_members\":true}}}"; static const char* ADDITIONAL_MESSAGES_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"limit\":20,\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true}}}"; static const char* CONTINUE_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"types\":[\"m.fully_read\",\"m.tag\",\"qm.last_read_message_timestamp\"],\"lazy_load_members\":true}}}"; @@ -1661,8 +1661,7 @@ namespace QuickMedia { const rapidjson::Value &events_json = GetMember(state_json, "events"); events_add_user_info(events_json, room); events_set_room_info(events_json, room); - if(!is_additional_messages_sync) - events_add_pinned_events(events_json, room); + events_add_pinned_events(events_json, room); } const rapidjson::Value &account_data_json = GetMember(it.value, "account_data"); @@ -1702,8 +1701,7 @@ namespace QuickMedia { ui_thread_tasks.push([this, room]{ delegate->join_room(room); }); events_add_messages(events_json, room, MessageDirection::AFTER, has_unread_notifications); - if(!is_additional_messages_sync) - events_add_pinned_events(events_json, room); + events_add_pinned_events(events_json, room); } else { set_room_info_to_users_if_empty(room, my_user_id); if(account_data_json.IsObject()) { @@ -3801,34 +3799,67 @@ namespace QuickMedia { return PluginResult::OK; } - PluginResult Matrix::pin_message(RoomData *room, const std::string &event_id) { - if(!is_initial_sync_finished()) { - show_notification("QuickMedia", "Can't pin messages while sync is in progress", Urgency::CRITICAL); + PluginResult Matrix::get_pinned_events(RoomData *room, std::vector &pinned_events) { + std::vector additional_args = { + { "-H", "Authorization: Bearer " + access_token } + }; + + char url[512]; + snprintf(url, sizeof(url), "%s/_matrix/client/r0/rooms/%s/state/m.room.pinned_events/", homeserver.c_str(), room->id.c_str()); + + rapidjson::Document json_root; + std::string err_msg; + DownloadResult download_result = download_json(json_root, url, std::move(additional_args), true, &err_msg); + if(download_result != DownloadResult::OK) return download_result_to_plugin_result(download_result); + + if(!json_root.IsObject()) { + show_notification("QuickMedia", "Failed to parse server response", Urgency::CRITICAL); return PluginResult::ERR; } - room->acquire_room_lock(); - auto pinned_events = room->get_pinned_events_thread_unsafe(); - room->release_room_lock(); + const rapidjson::Value &errcode_json = GetMember(json_root, "errcode"); + if(errcode_json.IsString() && strcmp(errcode_json.GetString(), "M_NOT_FOUND") != 0) { + const rapidjson::Value &error_json = GetMember(json_root, "error"); + if(error_json.IsString()) { + show_notification("QuickMedia", "Failed to get pinned events for room " + room->id + ", error: " + std::string(error_json.GetString(), error_json.GetStringLength()), Urgency::CRITICAL); + return PluginResult::ERR; + } + } + + const rapidjson::Value &pinned_json = GetMember(json_root, "pinned"); + if(!pinned_json.IsArray()) + return PluginResult::ERR; + + for(const rapidjson::Value &event_json : pinned_json.GetArray()) { + if(!event_json.IsString()) + continue; + pinned_events.emplace_back(event_json.GetString(), event_json.GetStringLength()); + } + + return PluginResult::OK; + } + + PluginResult Matrix::pin_message(RoomData *room, const std::string &event_id) { + std::vector pinned_events; + PluginResult result = get_pinned_events(room, pinned_events); + if(result != PluginResult::OK) + return result; pinned_events.push_back(event_id); return set_pinned_events(room, pinned_events, true); } PluginResult Matrix::unpin_message(RoomData *room, const std::string &event_id) { - if(!is_initial_sync_finished()) { - show_notification("QuickMedia", "Can't unpin messages while sync is in progress", Urgency::CRITICAL); - return PluginResult::ERR; - } - - room->acquire_room_lock(); - auto pinned_events = room->get_pinned_events_thread_unsafe(); - room->release_room_lock(); + std::vector pinned_events; + PluginResult result = get_pinned_events(room, pinned_events); + if(result != PluginResult::OK) + return result; auto find_it = std::find(pinned_events.begin(), pinned_events.end(), event_id); - if(find_it != pinned_events.end()) - pinned_events.erase(find_it); - + if(find_it == pinned_events.end()) + return PluginResult::OK; + + pinned_events.erase(find_it); return set_pinned_events(room, pinned_events, false); } -- cgit v1.2.3