aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-11-04 14:16:25 +0100
committerdec05eba <dec05eba@protonmail.com>2020-11-04 14:16:25 +0100
commitc22aab0620c79a80535c85c0dad87a1f288a884c (patch)
tree1daf861ff8d30908d902fe2f81f8450ee0b813e7 /src/plugins
parentdb8ff2f73dd2f8a16f547d8f397753dee64341c9 (diff)
Matrix: show membership events, unimplemented events, do not fetch users remote during cache (slow)
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/Matrix.cpp122
1 files changed, 106 insertions, 16 deletions
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 198b2fd..11d0746 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -995,6 +995,7 @@ namespace QuickMedia {
sync_data.messages.insert(sync_data.messages.end(), room_messages.begin() + room->messages_read_index, room_messages.end());
room->messages_read_index = room_messages.size();
} else {
+ // TODO: BUG
fprintf(stderr, "Unexpected behavior!!!! get_room_sync_data said read index is %zu but we only have %zu messages\n", room->messages_read_index, room_messages.size());
room->messages_read_index = room_messages.size();
}
@@ -1032,7 +1033,10 @@ namespace QuickMedia {
size_t num_new_messages = num_messages_after - num_messages_before;
messages.insert(messages.end(), room->get_messages_thread_unsafe().begin(), room->get_messages_thread_unsafe().begin() + num_new_messages);
room->messages_read_index += num_new_messages;
- assert(room->messages_read_index <= room->get_messages_thread_unsafe().size());
+ //assert(room->messages_read_index <= num_messages_after);
+ // TODO: BUG
+ if(room->messages_read_index >= num_messages_after)
+ room->messages_read_index = num_messages_after;
room->release_room_lock();
return PluginResult::OK;
}
@@ -1293,15 +1297,21 @@ namespace QuickMedia {
if(!content_json.IsObject())
continue;
- const rapidjson::Value &membership_json = GetMember(content_json, "membership");
- if(!membership_json.IsString() || strcmp(membership_json.GetString(), "join") != 0)
- continue;
-
std::string sender_json_str = sender_json.GetString();
parse_user_info(content_json, sender_json_str, room_data);
}
}
+ static std::string thumbnail_url_extract_media_id(const std::string &media_url) {
+ size_t start = 0;
+ size_t end = media_url.size();
+ if(strncmp(media_url.c_str(), "mxc://", 6) == 0)
+ start = 6;
+ if(media_url.size() >= start + 5 && strncmp(media_url.c_str() + media_url.size() - 5, "#auto", 5) == 0)
+ end = media_url.size() - 5;
+ return media_url.substr(start, end - start);
+ }
+
std::shared_ptr<UserInfo> Matrix::parse_user_info(const rapidjson::Value &json, const std::string &user_id, RoomData *room_data) {
assert(json.IsObject());
std::string avatar_url_str;
@@ -1313,9 +1323,7 @@ namespace QuickMedia {
auto user_info = std::make_shared<UserInfo>();
user_info->user_id = user_id;
- user_info->avatar_url = std::move(avatar_url_str);
- if(strncmp(user_info->avatar_url.c_str(), "mxc://", 6) == 0)
- user_info->avatar_url.erase(user_info->avatar_url.begin(), user_info->avatar_url.begin() + 6);
+ user_info->avatar_url = thumbnail_url_extract_media_id(avatar_url_str);
if(!user_info->avatar_url.empty())
user_info->avatar_url = homeserver + "/_matrix/media/r0/thumbnail/" + user_info->avatar_url + "?width=32&height=32&method=crop"; // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
user_info->display_name = display_name_json.IsString() ? display_name_json.GetString() : user_id;
@@ -1554,11 +1562,20 @@ namespace QuickMedia {
if(!event_item_json.IsObject())
return nullptr;
- const rapidjson::Value &sender_json = GetMember(event_item_json, "sender");
- if(!sender_json.IsString())
+ const rapidjson::Value *sender_json = &GetMember(event_item_json, "sender");
+ const rapidjson::Value *sender_json_orig = sender_json;
+ if(!sender_json->IsString())
return nullptr;
- std::string sender_json_str = sender_json.GetString();
+ bool sent_by_somebody_else = false;
+ const rapidjson::Value *state_key_json = &GetMember(event_item_json, "state_key");
+ if(state_key_json->IsString() && state_key_json->GetStringLength() != 0) {
+ if(strcmp(sender_json->GetString(), state_key_json->GetString()) != 0)
+ sent_by_somebody_else = true;
+ sender_json = state_key_json;
+ }
+
+ std::string sender_json_str = sender_json->GetString();
const rapidjson::Value &event_id_json = GetMember(event_item_json, "event_id");
if(!event_id_json.IsString())
@@ -1577,6 +1594,10 @@ namespace QuickMedia {
return nullptr;
}
+ auto user_sender = user;
+ if(sent_by_somebody_else)
+ user_sender = get_user_by_id(room_data, sender_json_orig->GetString());
+
time_t timestamp = 0;
const rapidjson::Value &origin_server_ts = GetMember(event_item_json, "origin_server_ts");
if(origin_server_ts.IsNumber())
@@ -1634,8 +1655,68 @@ namespace QuickMedia {
return message;
}
- if(strcmp(type_json.GetString(), "m.room.message") != 0)
- return nullptr;
+ if(strcmp(type_json.GetString(), "m.room.message") == 0) {
+
+ } else if(strcmp(type_json.GetString(), "m.room.member") == 0) {
+ std::string body;
+ const rapidjson::Value &membership_json = GetMember(*content_json, "membership");
+ 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_content_json = GetMember(unsigned_json, "prev_content");
+ if(prev_content_json.IsObject()) {
+ 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");
+ const rapidjson::Value &new_avatar_url_json = GetMember(*content_json, "avatar_url");
+ if(new_displayname_json.IsString() && (!prev_displayname_json.IsString() || strcmp(new_displayname_json.GetString(), prev_displayname_json.GetString()) != 0))
+ body = user->display_name + " changed their display name to " + std::string(new_displayname_json.GetString());
+ else if(!new_displayname_json.IsString() && prev_displayname_json.IsString())
+ body = user->display_name + " removed their display name";
+ else if(new_avatar_url_json.IsString() && (!prev_avatar_url_json.IsString() || strcmp(new_avatar_url_json.GetString(), prev_avatar_url_json.GetString()) != 0))
+ body = user->display_name + " changed their profile picture";
+ else if(!new_avatar_url_json.IsString() && prev_avatar_url_json.IsString())
+ body = user->display_name + " removed their profile picture.";
+ else
+ body = user->display_name + " joined the room";
+ } else {
+ body = user->display_name + " joined the room";
+ }
+ } else {
+ body = user->display_name + " joined the room";
+ }
+ } else if(strcmp(membership_json.GetString(), "leave") == 0) {
+ if(sent_by_somebody_else)
+ body = user->display_name + " was kicked from the room by " + user_sender->display_name;
+ else
+ body = user->display_name + " left the room";
+ } else if(strcmp(membership_json.GetString(), "invite") == 0) {
+ body = user->display_name + " was invited to the room by " + user_sender->display_name;
+ } else if(strcmp(membership_json.GetString(), "ban") == 0) {
+ body = user->display_name + " was banned from the room by " + user_sender->display_name;
+ } else {
+ body = "unimplemented membership: " + std::string(membership_json.GetString());
+ }
+ auto message = std::make_shared<Message>();
+ message->type = MessageType::MEMBERSHIP;
+ message->user = user;
+ message->event_id = event_id_str;
+ message->body = std::move(body);
+ message->related_event_id = std::move(related_event_id);
+ message->related_event_type = related_event_type;
+ message->timestamp = timestamp;
+ return message;
+ } else {
+ auto message = std::make_shared<Message>();
+ message->type = MessageType::UNIMPLEMENTED;
+ message->user = user;
+ message->event_id = event_id_str;
+ message->body = "unimplemented event type: " + std::string(type_json.GetString());
+ message->related_event_id = std::move(related_event_id);
+ message->related_event_type = related_event_type;
+ message->timestamp = timestamp;
+ return message;
+ }
const rapidjson::Value &body_json = GetMember(*content_json, "body");
if(!body_json.IsString())
@@ -1767,11 +1848,11 @@ namespace QuickMedia {
continue;
const rapidjson::Value &url_json = GetMember(content_json, "url");
- if(!url_json.IsString() || strncmp(url_json.GetString(), "mxc://", 6) != 0)
+ if(!url_json.IsString())
continue;
std::string url_json_str = url_json.GetString() + 6;
- room_data->set_avatar_url(homeserver + "/_matrix/media/r0/thumbnail/" + std::move(url_json_str) + "?width=32&height=32&method=crop");
+ room_data->set_avatar_url(homeserver + "/_matrix/media/r0/thumbnail/" + thumbnail_url_extract_media_id(url_json_str) + "?width=32&height=32&method=crop");
}
bool has_room_name = room_data->has_name();
@@ -3081,7 +3162,7 @@ namespace QuickMedia {
auto user = room->get_user_by_id(user_id);
if(user)
return user;
-
+ #if 0
// TODO: Instead of guessing notification limit with 100, accumulate rooms unread_notifications count and use that as the limit
// (and take into account that notification response may have notifications after call to sync above).
char url[512];
@@ -3097,6 +3178,15 @@ namespace QuickMedia {
// Is this a synapse bug? sometimes lazy_fetch_members doesn't contain all related clients
fprintf(stderr, "User was not available locally, fetched from server...\n");
return parse_user_info(json_root, user_id, room);
+ #else
+ fprintf(stderr, "Unknown user: %s, creating locally... synapse bug?\n", user_id.c_str());
+ auto user_info = std::make_shared<UserInfo>();
+ user_info->user_id = user_id;
+ user_info->display_name = user_id;
+ user_info->display_name_color = user_id_to_color(user_id);
+ room->add_user(user_info);
+ return user_info;
+ #endif
}
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 {