aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-11-18 04:46:54 +0100
committerdec05eba <dec05eba@protonmail.com>2020-11-18 08:58:03 +0100
commit053ffc2ea6cf22f2b4d1ab37805f57c48d114871 (patch)
treeb8b23a6e87238a4526f4586095a753eb76bae920
parent6ce1376869dfa560221085edbbfc0ac7cd7ef751 (diff)
Matrix: attempt fix double messages for sent messages with construct, missing displayname/avatars and invite to join modifying the wrong user
-rw-r--r--plugins/Matrix.hpp2
-rw-r--r--src/QuickMedia.cpp59
-rw-r--r--src/plugins/Matrix.cpp54
3 files changed, 73 insertions, 42 deletions
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index 4514b4c..e60889f 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -512,7 +512,7 @@ namespace QuickMedia {
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::recursive_mutex room_data_mutex;
- std::string user_id;
+ std::string my_user_id;
std::string access_token;
std::string homeserver;
std::optional<int> upload_limit;
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 71ba8d2..f66d419 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3364,7 +3364,8 @@ namespace QuickMedia {
std::string event_id;
};
- std::vector<ProvisionalMessage> unresolved_provisional_messages; // |event_id| is always empty in this. Use |message->event_id| instead
+ // This is needed to keep the message shared ptr alive. TODO: Remove this shit, maybe even use raw pointers.
+ std::unordered_map<std::string, ProvisionalMessage> sent_messages; // |event_id| is always empty in this. Use |message->event_id| instead
std::optional<ProvisionalMessage> provisional_message;
MessageQueue<ProvisionalMessage> provisional_message_queue;
MessageQueue<std::function<ProvisionalMessage()>> post_task_queue;
@@ -3378,22 +3379,21 @@ namespace QuickMedia {
};
std::thread post_thread(post_thread_handler);
- auto resolve_provisional_messages = [&unresolved_provisional_messages](Messages &messages) {
- if(messages.empty() || unresolved_provisional_messages.empty())
- return;
+ auto filter_my_messages = [&me](Messages &messages) {
+ for(auto it = messages.begin(); it != messages.end();) {
+ if((*it)->user == me)
+ it = messages.erase(it);
+ else
+ ++it;
+ }
+ };
- for(auto it = unresolved_provisional_messages.begin(); it != unresolved_provisional_messages.end();) {
- auto find_it = std::find_if(messages.cbegin(), messages.cend(), [&it](const std::shared_ptr<Message> &message) {
- return message->event_id == it->message->event_id;
- });
- if(find_it != messages.end()) {
- it->body_item->set_description_color(sf::Color::White);
- it->body_item->userdata = find_it->get(); // This is ok because the message is added to |all_messages|
- it = unresolved_provisional_messages.erase(it);
- messages.erase(find_it);
- } else {
+ auto filter_sent_messages = [&sent_messages](Messages &messages) {
+ for(auto it = messages.begin(); it != messages.end();) {
+ if(sent_messages.find((*it)->event_id) != sent_messages.end())
+ it = messages.erase(it);
+ else
++it;
- }
}
};
@@ -3414,7 +3414,7 @@ namespace QuickMedia {
tabs[MESSAGES_TAB_INDEX].body->select_last_item();
}
};
-
+
chat_input.on_submit_callback = [this, &tabs, &me, &chat_input, &selected_tab, &current_room, &new_page, &chat_state, &currently_operating_on_item, &post_task_queue, &unreferenced_events, &find_body_item_by_event_id](std::string text) mutable {
if(!current_room)
return false;
@@ -3509,14 +3509,17 @@ namespace QuickMedia {
void *related_to_message = currently_operating_on_item->userdata;
message->related_event_type = RelatedEventType::EDIT;
message->related_event_id = static_cast<Message*>(related_to_message)->event_id;
- auto body_item = find_body_item_by_event_id(tabs[MESSAGES_TAB_INDEX].body->items.data(), tabs[MESSAGES_TAB_INDEX].body->items.size(), message->related_event_id);
+ size_t body_item_index = 0;
+ auto body_item = find_body_item_by_event_id(tabs[MESSAGES_TAB_INDEX].body->items.data(), tabs[MESSAGES_TAB_INDEX].body->items.size(), message->related_event_id, &body_item_index);
if(body_item) {
- body_item->set_description(text);
- body_item->set_description_color(provisional_message_color);
- unreferenced_events.push_back(message);
- post_task_queue.push([this, &current_room, text, related_to_message, message]() {
+ auto body_item_shared_ptr = tabs[MESSAGES_TAB_INDEX].body->items[body_item_index];
+ body_item_shared_ptr->set_description(text);
+ body_item_shared_ptr->set_description_color(provisional_message_color);
+ //unreferenced_events.push_back(message);
+ post_task_queue.push([this, &current_room, text, related_to_message, message, body_item_shared_ptr]() {
ProvisionalMessage provisional_message;
provisional_message.message = message;
+ provisional_message.body_item = body_item_shared_ptr;
if(matrix->post_edit(current_room, text, related_to_message, provisional_message.event_id) != PluginResult::OK)
fprintf(stderr, "Failed to post matrix edit\n");
return provisional_message;
@@ -3900,7 +3903,7 @@ namespace QuickMedia {
}
};
- auto cleanup_tasks = [&set_read_marker_future, &fetch_message_future, &typing_state_queue, &typing_state_thread, &post_task_queue, &provisional_message_queue, &post_thread, &tabs]() {
+ auto cleanup_tasks = [&set_read_marker_future, &fetch_message_future, &typing_state_queue, &typing_state_thread, &post_task_queue, &provisional_message_queue, &fetched_messages_set, &sent_messages, &post_thread, &tabs]() {
set_read_marker_future.cancel();
fetch_message_future.cancel();
typing_state_queue.close();
@@ -3914,6 +3917,8 @@ namespace QuickMedia {
post_thread.join();
}
provisional_message_queue.clear();
+ fetched_messages_set.clear();
+ sent_messages.clear();
//unreferenced_event_by_room.clear();
@@ -4327,7 +4332,8 @@ namespace QuickMedia {
if(!provisional_message->event_id.empty()) {
provisional_message->message->event_id = std::move(provisional_message->event_id);
- unresolved_provisional_messages.push_back(provisional_message.value());
+ provisional_message->body_item->set_description_color(sf::Color::White);
+ sent_messages[provisional_message->message->event_id] = std::move(provisional_message.value());
} else if(provisional_message->body_item) {
provisional_message->body_item->set_description("Failed to send: " + provisional_message->body_item->get_description());
provisional_message->body_item->set_description_color(sf::Color::Red);
@@ -4340,7 +4346,7 @@ namespace QuickMedia {
matrix->get_room_sync_data(current_room, sync_data);
if(!sync_data.messages.empty()) {
all_messages.insert(all_messages.end(), sync_data.messages.begin(), sync_data.messages.end());
- resolve_provisional_messages(sync_data.messages);
+ filter_my_messages(sync_data.messages);
filter_existing_messages(sync_data.messages);
}
add_new_messages_to_current_room(sync_data.messages);
@@ -4358,6 +4364,7 @@ namespace QuickMedia {
all_messages.insert(all_messages.end(), new_messages.begin(), new_messages.end());
if(new_messages.empty())
fetched_enough_messages = true;
+ filter_sent_messages(new_messages);
filter_existing_messages(new_messages);
fprintf(stderr, "Finished fetching older messages, num new messages: %zu\n", new_messages.size());
bool move_to_bottom = false;
@@ -4603,8 +4610,8 @@ namespace QuickMedia {
fetched_messages_set.insert(message->event_id);
}
all_messages.insert(all_messages.end(), all_messages_new.begin(), all_messages_new.end());
- auto me = matrix->get_me(current_room);
- resolve_provisional_messages(all_messages_new);
+ me = matrix->get_me(current_room);
+ filter_sent_messages(all_messages_new);
add_new_messages_to_current_room(all_messages_new);
modify_related_messages_in_current_room(all_messages_new);
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index ee61c23..9998b48 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -101,7 +101,7 @@ namespace QuickMedia {
UserInfo::UserInfo(RoomData *room, std::string user_id) :
room(room), display_name_color(user_id_to_color(user_id)), user_id(user_id), resolve_state(UserResolveState::NOT_RESOLVED)
{
- display_name = std::move(user_id);
+ display_name = user_id;
}
UserInfo::UserInfo(RoomData *room, std::string user_id, std::string display_name, std::string avatar_url) :
@@ -1368,7 +1368,6 @@ namespace QuickMedia {
room->set_prev_batch(prev_batch_json.GetString());
}
- // TODO: Use /_matrix/client/r0/notifications ? or remove this and always look for displayname/user_id in messages
bool has_unread_notifications = false;
const rapidjson::Value &unread_notification_json = GetMember(it.value, "unread_notifications");
if(unread_notification_json.IsObject() && !is_additional_messages_sync) {
@@ -1382,7 +1381,7 @@ namespace QuickMedia {
const rapidjson::Value &events_json = GetMember(timeline_json, "events");
events_add_user_info(events_json, room);
events_set_room_name(events_json, room);
- set_room_name_to_users_if_empty(room, user_id);
+ set_room_name_to_users_if_empty(room, my_user_id);
if(account_data_json.IsObject()) {
const rapidjson::Value &events_json = GetMember(account_data_json, "events");
@@ -1397,7 +1396,7 @@ namespace QuickMedia {
if(!is_additional_messages_sync)
events_add_pinned_events(events_json, room);
} else {
- set_room_name_to_users_if_empty(room, user_id);
+ set_room_name_to_users_if_empty(room, my_user_id);
if(account_data_json.IsObject()) {
const rapidjson::Value &events_json = GetMember(account_data_json, "events");
auto me = get_me(room);
@@ -1784,8 +1783,9 @@ namespace QuickMedia {
if(strcmp(membership_json.GetString(), "join") == 0) {
const rapidjson::Value &unsigned_json = GetMember(event_item_json, "unsigned");
if(unsigned_json.IsObject()) {
+ const rapidjson::Value &prev_sender = GetMember(unsigned_json, "prev_sender");
const rapidjson::Value &prev_content_json = GetMember(unsigned_json, "prev_content");
- if(prev_content_json.IsObject()) {
+ if(prev_content_json.IsObject() && (!prev_sender.IsString() || strcmp(prev_sender.GetString(), user->user_id.c_str()) == 0)) {
const rapidjson::Value &prev_displayname_json = GetMember(prev_content_json, "displayname");
const rapidjson::Value &prev_avatar_url_json = GetMember(prev_content_json, "avatar_url");
const rapidjson::Value &new_displayname_json = GetMember(*content_json, "displayname");
@@ -2003,7 +2003,7 @@ namespace QuickMedia {
std::vector<std::shared_ptr<UserInfo>> users_excluding_me;
if(!has_room_name || !has_room_avatar_url || room->name_is_fallback || room->avatar_is_fallback)
- users_excluding_me = room->get_users_excluding_me(user_id);
+ users_excluding_me = room->get_users_excluding_me(my_user_id);
if(!has_room_name) {
room->set_name(combine_user_display_names_for_room_name(users_excluding_me, room_creator_user_id));
@@ -2255,7 +2255,7 @@ namespace QuickMedia {
std::string desc;
LeaveType leave_type;
if(strcmp(membership_json.GetString(), "leave") == 0) {
- if(strcmp(sender_json.GetString(), user_id.c_str()) == 0) {
+ if(strcmp(sender_json.GetString(), my_user_id.c_str()) == 0) {
leave_type = LeaveType::LEAVE;
} else {
leave_type = LeaveType::KICKED;
@@ -2929,7 +2929,7 @@ namespace QuickMedia {
// such as pantalaimon
json_root.AddMember("homeserver", rapidjson::StringRef(homeserver.c_str()), request_data.GetAllocator());
- this->user_id = user_id_json.GetString();
+ this->my_user_id = user_id_json.GetString();
this->access_token = access_token_json.GetString();
this->homeserver = homeserver;
@@ -2964,7 +2964,7 @@ namespace QuickMedia {
// Make sure all fields are reset here!
rooms.clear();
room_data_by_id.clear();
- user_id.clear();
+ my_user_id.clear();
access_token.clear();
homeserver.clear();
upload_limit.reset();
@@ -3063,7 +3063,7 @@ namespace QuickMedia {
std::string access_token = access_token_json.GetString();
std::string homeserver = homeserver_json.GetString();
- this->user_id = std::move(user_id);
+ this->my_user_id = std::move(user_id);
this->access_token = std::move(access_token);
this->homeserver = std::move(homeserver);
return PluginResult::OK;
@@ -3086,7 +3086,7 @@ namespace QuickMedia {
};
std::string server_response;
- DownloadResult download_result = download_to_string(homeserver + "/_matrix/client/r0/rooms/" + room->id + "/typing/" + url_param_encode(user_id) , server_response, std::move(additional_args), use_tor, true);
+ DownloadResult download_result = download_to_string(homeserver + "/_matrix/client/r0/rooms/" + room->id + "/typing/" + url_param_encode(my_user_id) , server_response, std::move(additional_args), use_tor, true);
return download_result_to_plugin_result(download_result);
}
@@ -3106,7 +3106,7 @@ namespace QuickMedia {
};
std::string server_response;
- DownloadResult download_result = download_to_string(homeserver + "/_matrix/client/r0/rooms/" + room->id + "/typing/" + url_param_encode(user_id), server_response, std::move(additional_args), use_tor, true);
+ DownloadResult download_result = download_to_string(homeserver + "/_matrix/client/r0/rooms/" + room->id + "/typing/" + url_param_encode(my_user_id), server_response, std::move(additional_args), use_tor, true);
return download_result_to_plugin_result(download_result);
}
@@ -3199,7 +3199,7 @@ namespace QuickMedia {
bool Matrix::was_message_posted_by_me(void *message) {
Message *message_typed = (Message*)message;
- return user_id == message_typed->user->user_id;
+ return my_user_id == message_typed->user->user_id;
}
std::string Matrix::message_get_author_displayname(Message *message) const {
@@ -3239,7 +3239,7 @@ namespace QuickMedia {
}
std::shared_ptr<UserInfo> Matrix::get_me(RoomData *room) {
- return get_user_by_id(room, user_id);
+ return get_user_by_id(room, my_user_id);
}
RoomData* Matrix::get_room_by_id(const std::string &id) {
@@ -3336,6 +3336,7 @@ namespace QuickMedia {
}
void Matrix::update_room_users(RoomData *room) {
+#if 1
std::vector<CommandArg> additional_args = {
{ "-H", "Authorization: Bearer " + access_token }
};
@@ -3360,7 +3361,8 @@ namespace QuickMedia {
const rapidjson::Value &avatar_url_json = GetMember(joined_obj.value, "avatar_url");
const rapidjson::Value &display_name_json = GetMember(joined_obj.value, "display_name");
- auto user = get_user_by_id(room, std::string(joined_obj.name.GetString(), joined_obj.name.GetStringLength()));
+ std::string user_id(joined_obj.name.GetString(), joined_obj.name.GetStringLength());
+ auto user = get_user_by_id(room, user_id);
assert(user);
std::string display_name = display_name_json.IsString() ? display_name_json.GetString() : user_id;
@@ -3372,6 +3374,28 @@ namespace QuickMedia {
room->set_user_avatar_url(user, std::move(avatar_url));
room->set_user_display_name(user, std::move(display_name));
}
+#else
+ std::vector<CommandArg> additional_args = {
+ { "-H", "Authorization: Bearer " + access_token }
+ };
+
+ // TODO: Use at param? which is room->get_prev_batch();
+ char url[512];
+ snprintf(url, sizeof(url), "%s/_matrix/client/r0/rooms/%s/members?membership=join", homeserver.c_str(), room->id.c_str());
+
+ rapidjson::Document json_root;
+ DownloadResult download_result = download_json(json_root, url, std::move(additional_args), true);
+ if(download_result != DownloadResult::OK || !json_root.IsObject()) {
+ fprintf(stderr, "Fetching users for room %s failed!\n", room->id.c_str());
+ return;
+ }
+
+ const rapidjson::Value &chunk_json = GetMember(json_root, "chunk");
+ if(!chunk_json.IsArray())
+ return;
+
+ events_add_user_info(chunk_json, room);
+#endif
}
// TODO: GET the filter to check if its valid?