aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Matrix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Matrix.cpp')
-rw-r--r--src/plugins/Matrix.cpp148
1 files changed, 93 insertions, 55 deletions
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 7c170c9..0c94dd5 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -84,6 +84,30 @@ namespace QuickMedia {
}
}
+ static sf::Color user_id_to_color(const std::string &user_id) {
+ uint32_t color = 2166136261;
+ for(unsigned char c : user_id) {
+ color = (color * 16777619) ^ c;
+ }
+ sf::Uint8 *col = (sf::Uint8*)&color;
+ sf::Color result(col[0], col[1], col[2]);
+ result.r = std::min(255, 80 + (int)result.r);
+ result.g = std::min(255, 80 + (int)result.g);
+ result.b = std::min(255, 80 + (int)result.b);
+ result.a = 255;
+ return result;
+ }
+
+ UserInfo::UserInfo(RoomData *room, std::string user_id) :
+ room(room), display_name_color(user_id_to_color(user_id)), user_id(std::move(user_id)), display_name(user_id) {
+
+ }
+
+ UserInfo::UserInfo(RoomData *room, std::string user_id, std::string display_name, std::string avatar_url) :
+ room(room), display_name_color(user_id_to_color(user_id)), user_id(std::move(user_id)), display_name(std::move(display_name)), avatar_url(std::move(avatar_url)) {
+
+ }
+
std::shared_ptr<UserInfo> RoomData::get_user_by_id(const std::string &user_id) {
std::lock_guard<std::recursive_mutex> lock(room_mutex);
auto user_it = user_info_by_user_id.find(user_id);
@@ -102,11 +126,33 @@ namespace QuickMedia {
user->read_marker_event_id = event_id;
}
- std::string RoomData::get_user_read_marker(std::shared_ptr<UserInfo> &user) {
+ std::string RoomData::get_user_read_marker(const std::shared_ptr<UserInfo> &user) {
std::lock_guard<std::recursive_mutex> lock(user_mutex);
return user->read_marker_event_id;
}
+ std::string RoomData::get_user_display_name(const std::shared_ptr<UserInfo> &user) {
+ std::lock_guard<std::recursive_mutex> lock(user_mutex);
+ return user->display_name;
+ }
+
+ std::string RoomData::get_user_avatar_url(const std::shared_ptr<UserInfo> &user) {
+ std::lock_guard<std::recursive_mutex> lock(user_mutex);
+ return user->avatar_url;
+ }
+
+ void RoomData::set_user_display_name(std::shared_ptr<UserInfo> &user, std::string display_name) {
+ std::lock_guard<std::recursive_mutex> lock(user_mutex);
+ user->display_name = std::move(display_name);
+ if(user->display_name.empty())
+ user->display_name = user->user_id;
+ }
+
+ void RoomData::set_user_avatar_url(std::shared_ptr<UserInfo> &user, std::string avatar_url) {
+ std::lock_guard<std::recursive_mutex> lock(user_mutex);
+ user->avatar_url = std::move(avatar_url);
+ }
+
void RoomData::prepend_messages_reverse(const std::vector<std::shared_ptr<Message>> &new_messages) {
std::lock_guard<std::recursive_mutex> lock(room_mutex);
for(auto it = new_messages.begin(); it != new_messages.end(); ++it) {
@@ -280,8 +326,9 @@ namespace QuickMedia {
}
void MatrixQuickMedia::add_invite(const std::string &room_id, const Invite &invite) {
+ std::string invited_by_display_name = invite.invited_by->room->get_user_display_name(invite.invited_by);
auto body_item = BodyItem::create(invite.room_name);
- body_item->set_description("Invited by " + invite.invited_by->display_name + " (" + invite.invited_by->user_id + ")");
+ body_item->set_description("Invited by " + invited_by_display_name + " (" + invite.invited_by->user_id + ")");
body_item->url = room_id;
body_item->thumbnail_url = invite.room_avatar_url;
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
@@ -289,7 +336,7 @@ namespace QuickMedia {
body_item->set_timestamp(invite.timestamp);
invites_page->add_body_item(std::move(body_item));
if(invite.new_invite)
- show_notification("QuickMedia matrix - " + invite.room_name, "You were invited to " + invite.room_name + " by " + invite.invited_by->display_name + " (" + invite.invited_by->user_id + ")");
+ show_notification("QuickMedia matrix - " + invite.room_name, "You were invited to " + invite.room_name + " by " + invited_by_display_name + " (" + invite.invited_by->user_id + ")");
}
void MatrixQuickMedia::remove_invite(const std::string &room_id) {
@@ -1381,20 +1428,6 @@ namespace QuickMedia {
return PluginResult::OK;
}
- static sf::Color user_id_to_color(const std::string &user_id) {
- uint32_t color = 2166136261;
- for(unsigned char c : user_id) {
- color = (color * 16777619) ^ c;
- }
- sf::Uint8 *col = (sf::Uint8*)&color;
- sf::Color result(col[0], col[1], col[2]);
- result.r = std::min(255, 80 + (int)result.r);
- result.g = std::min(255, 80 + (int)result.g);
- result.b = std::min(255, 80 + (int)result.b);
- result.a = 255;
- return result;
- }
-
void Matrix::events_add_user_info(const rapidjson::Value &events_json, RoomData *room_data) {
if(!events_json.IsArray())
return;
@@ -1439,14 +1472,11 @@ namespace QuickMedia {
const rapidjson::Value &display_name_json = GetMember(json, "displayname");
- auto user_info = std::make_shared<UserInfo>();
- user_info->user_id = user_id;
- 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;
- user_info->display_name_color = user_id_to_color(user_id);
-
+ std::string display_name = display_name_json.IsString() ? display_name_json.GetString() : user_id;
+ std::string avatar_url = thumbnail_url_extract_media_id(avatar_url_str);
+ if(!avatar_url.empty())
+ avatar_url = homeserver + "/_matrix/media/r0/thumbnail/" + avatar_url + "?width=32&height=32&method=crop"; // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
+ auto user_info = std::make_shared<UserInfo>(room_data, user_id, std::move(display_name), std::move(avatar_url));
// Overwrites user data
room_data->add_user(user_info);
return user_info;
@@ -1590,6 +1620,7 @@ namespace QuickMedia {
// TODO: Preallocate
std::vector<std::shared_ptr<Message>> new_messages;
auto me = get_me(room_data);
+ std::string my_display_name = room_data->get_user_display_name(me);
for(const rapidjson::Value &event_item_json : events_json.GetArray()) {
std::shared_ptr<Message> new_message = parse_message_event(event_item_json, room_data);
@@ -1618,7 +1649,7 @@ namespace QuickMedia {
// TODO: Is @room ok? shouldn't we also check if the user has permission to do @room? (only when notifications are limited to @mentions)
// TODO: Is comparing against read marker timestamp ok enough?
if(me && message->timestamp > read_marker_message_timestamp)
- message->mentions_me = message_contains_user_mention(message->body, me->display_name) || message_contains_user_mention(message->body, me->user_id) || message_contains_user_mention(message->body, "@room");
+ message->mentions_me = message_contains_user_mention(message->body, my_display_name) || message_contains_user_mention(message->body, me->user_id) || message_contains_user_mention(message->body, "@room");
}
}
@@ -1726,6 +1757,8 @@ namespace QuickMedia {
if(strcmp(type_json.GetString(), "m.room.message") == 0) {
} else if(strcmp(type_json.GetString(), "m.room.member") == 0) {
+ std::string user_display_name = room_data->get_user_display_name(user);
+ std::string sender_display_name = room_data->get_user_display_name(user_sender);
std::string body;
const rapidjson::Value &membership_json = GetMember(*content_json, "membership");
if(strcmp(membership_json.GetString(), "join") == 0) {
@@ -1737,31 +1770,40 @@ namespace QuickMedia {
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";
+ if(new_displayname_json.IsString() && (!prev_displayname_json.IsString() || strcmp(new_displayname_json.GetString(), prev_displayname_json.GetString()) != 0)) {
+ std::string new_displayname_str = std::string(new_displayname_json.GetString());
+ body = user_display_name + " changed their display name to " + new_displayname_str;
+ room_data->set_user_display_name(user, std::move(new_displayname_str));
+ } else if(!new_displayname_json.IsString() && prev_displayname_json.IsString()) {
+ body = user_display_name + " removed their display name";
+ room_data->set_user_display_name(user, "");
+ } 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";
+ std::string new_avatar_url_str = thumbnail_url_extract_media_id(new_avatar_url_json.GetString());
+ if(!new_avatar_url_str.empty())
+ new_avatar_url_str = homeserver + "/_matrix/media/r0/thumbnail/" + new_avatar_url_str + "?width=32&height=32&method=crop"; // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
+ room_data->set_user_avatar_url(user, std::move(new_avatar_url_str));
+ } else if(!new_avatar_url_json.IsString() && prev_avatar_url_json.IsString()) {
+ body = user_display_name + " removed their profile picture.";
+ room_data->set_user_avatar_url(user, "");
+ } else {
+ body = user_display_name + " joined the room";
+ }
} else {
- body = user->display_name + " joined the room";
+ body = user_display_name + " joined the room";
}
} else {
- body = user->display_name + " joined the room";
+ 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;
+ body = user_display_name + " was kicked from the room by " + sender_display_name;
else
- body = user->display_name + " left the room";
+ 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;
+ body = user_display_name + " was invited to the room by " + 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;
+ body = user_display_name + " was banned from the room by " + sender_display_name;
} else {
body = "unimplemented membership: " + std::string(membership_json.GetString());
}
@@ -1831,7 +1873,7 @@ namespace QuickMedia {
message->type = MessageType::FILE;
} else if(strcmp(content_type.GetString(), "m.emote") == 0) { // this is a /me message, TODO: show /me messages differently
message->type = MessageType::TEXT;
- prefix = "*" + user->display_name + "* ";
+ prefix = "*" + room_data->get_user_display_name(user) + "* ";
} else if(strcmp(content_type.GetString(), "m.notice") == 0) { // TODO: show notices differently
message->type = MessageType::TEXT;
prefix = "* NOTICE * ";
@@ -1867,16 +1909,16 @@ namespace QuickMedia {
return user_id.substr(1, index - 1);
}
- static std::string combine_user_display_names_for_room_name(const std::vector<std::shared_ptr<UserInfo>> &user_info, const std::string &fallback_user_id) {
+ static std::string combine_user_display_names_for_room_name(std::vector<std::shared_ptr<UserInfo>> &user_info, const std::string &fallback_user_id) {
std::string result;
if(user_info.size() == 0)
result = extract_user_name_from_user_id(fallback_user_id);
else if(user_info.size() == 1)
- result = user_info[0]->display_name;
+ result = user_info[0]->room->get_user_display_name(user_info[0]);
else if(user_info.size() == 2)
- result = user_info[0]->display_name + " and " + user_info[1]->display_name;
+ result = user_info[0]->room->get_user_display_name(user_info[0]) + " and " + user_info[1]->room->get_user_display_name(user_info[1]);
else if(user_info.size() > 2)
- result = user_info[0]->display_name + ", " + user_info[1]->display_name + " and " + std::to_string(user_info.size() - 2) + " other(s)";
+ result = user_info[0]->room->get_user_display_name(user_info[0]) + ", " + user_info[1]->room->get_user_display_name(user_info[1]) + " and " + std::to_string(user_info.size() - 2) + " other(s)";
return result;
}
@@ -1956,10 +1998,10 @@ namespace QuickMedia {
if(users_excluding_me.empty()) {
auto user = get_user_by_id(room_data, creator_json.GetString());
if(user)
- room_data->set_avatar_url(user->avatar_url);
+ room_data->set_avatar_url(room_data->get_user_avatar_url(user));
} else {
// TODO: If there are multiple users, then we want to use some other type of avatar, not the first users avatar
- room_data->set_avatar_url(users_excluding_me.front()->avatar_url);
+ room_data->set_avatar_url(room_data->get_user_avatar_url(users_excluding_me.front()));
}
has_room_avatar_url = true;
}
@@ -3128,8 +3170,7 @@ namespace QuickMedia {
}
std::string Matrix::message_get_author_displayname(Message *message) const {
- // TODO: Thread safe?
- return message->user->display_name;
+ return message->user->room->get_user_display_name(message->user);
}
PluginResult Matrix::get_config(int *upload_size) {
@@ -3255,10 +3296,7 @@ namespace QuickMedia {
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);
+ auto user_info = std::make_shared<UserInfo>(room, user_id);
room->add_user(user_info);
return user_info;
#endif