aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/Matrix.hpp2
-rw-r--r--src/plugins/Matrix.cpp74
2 files changed, 52 insertions, 24 deletions
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index d9e6a97..20ad7da 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -451,6 +451,7 @@ namespace QuickMedia {
PluginResult parse_sync_room_data(const rapidjson::Value &rooms_json);
PluginResult get_previous_room_messages(RoomData *room_data);
void events_add_user_info(const rapidjson::Value &events_json, RoomData *room_data);
+ std::shared_ptr<UserInfo> parse_user_info(const rapidjson::Value &json, const std::string &user_id, RoomData *room_data);
void events_add_user_read_markers(const rapidjson::Value &events_json, RoomData *room_data);
void events_set_user_read_marker(const rapidjson::Value &events_json, RoomData *room_data, std::shared_ptr<UserInfo> &me);
void events_add_messages(const rapidjson::Value &events_json, RoomData *room_data, MessageDirection message_dir, bool has_unread_notifications);
@@ -469,6 +470,7 @@ namespace QuickMedia {
void set_next_batch(std::string new_next_batch);
std::string get_next_batch();
void clear_sync_cache_for_new_sync();
+ std::shared_ptr<UserInfo> get_user_by_id(RoomData *room, const std::string &user_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;
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 2e96cd0..5a85e8e 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -1307,28 +1307,33 @@ namespace QuickMedia {
if(!membership_json.IsString() || strcmp(membership_json.GetString(), "join") != 0)
continue;
- std::string avatar_url_str;
- const rapidjson::Value &avatar_url_json = GetMember(content_json, "avatar_url");
- if(avatar_url_json.IsString())
- avatar_url_str = avatar_url_json.GetString();
+ std::string sender_json_str = sender_json.GetString();
+ parse_user_info(content_json, sender_json_str, room_data);
+ }
+ }
- const rapidjson::Value &display_name_json = GetMember(content_json, "displayname");
+ 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;
+ const rapidjson::Value &avatar_url_json = GetMember(json, "avatar_url");
+ if(avatar_url_json.IsString())
+ avatar_url_str = avatar_url_json.GetString();
- std::string sender_json_str = sender_json.GetString();
+ const rapidjson::Value &display_name_json = GetMember(json, "displayname");
- auto user_info = std::make_shared<UserInfo>();
- user_info->user_id = sender_json_str;
- 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);
- 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() : sender_json_str;
- user_info->display_name_color = user_id_to_color(sender_json_str);
-
- // Overwrites user data
- room_data->add_user(std::move(user_info));
- }
+ 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);
+ 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);
+
+ // Overwrites user data
+ room_data->add_user(user_info);
+ return user_info;
}
void Matrix::events_add_user_read_markers(const rapidjson::Value &events_json, RoomData *room_data) {
@@ -1369,7 +1374,7 @@ namespace QuickMedia {
if(!user_id_json.IsString())
continue;
- auto user = room_data->get_user_by_id(user_id_json.GetString());
+ auto user = get_user_by_id(room_data, user_id_json.GetString());
if(!user) {
fprintf(stderr, "Read receipt for unknown user: %s, ignoring...\n", user_id_json.GetString());
continue;
@@ -1575,7 +1580,7 @@ namespace QuickMedia {
if(!content_json->IsObject())
return nullptr;
- auto user = room_data->get_user_by_id(sender_json_str);
+ auto user = get_user_by_id(room_data, sender_json_str);
if(!user) {
// Note: this is important because otherwise replying and such is broken
fprintf(stderr, "Warning: skipping unknown user: %s\n", sender_json_str.c_str());
@@ -1809,7 +1814,7 @@ namespace QuickMedia {
if(!has_room_avatar_url) {
if(users_excluding_me.empty()) {
- auto user = room_data->get_user_by_id(creator_json.GetString());
+ auto user = get_user_by_id(room_data, creator_json.GetString());
if(user)
room_data->set_avatar_url(user->avatar_url);
} else {
@@ -1971,7 +1976,7 @@ namespace QuickMedia {
events_add_user_info(events_json, &invite_room);
events_set_room_name(events_json, &invite_room);
- auto invited_by = invite_room.get_user_by_id(sender_json.GetString());
+ auto invited_by = get_user_by_id(&invite_room, sender_json.GetString());
if(!invited_by) {
fprintf(stderr, "Invited by unknown user. Bug in homeserver?\n");
break;
@@ -3015,7 +3020,7 @@ namespace QuickMedia {
}
std::shared_ptr<UserInfo> Matrix::get_me(RoomData *room) {
- return room->get_user_by_id(user_id);
+ return get_user_by_id(room, user_id);
}
RoomData* Matrix::get_room_by_id(const std::string &id) {
@@ -3082,6 +3087,27 @@ namespace QuickMedia {
delegate->clear_data();
}
+ std::shared_ptr<UserInfo> Matrix::get_user_by_id(RoomData *room, const std::string &user_id) {
+ auto user = room->get_user_by_id(user_id);
+ if(user)
+ return user;
+
+ // 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];
+ snprintf(url, sizeof(url), "%s/_matrix/client/r0/profile/%s", homeserver.c_str(), user_id.c_str());
+
+ rapidjson::Document json_root;
+ DownloadResult download_result = download_json(json_root, url, {}, true);
+ if(download_result != DownloadResult::OK || !json_root.IsObject()) {
+ fprintf(stderr, "Fetching profile for user %s failed!\n", user_id.c_str());
+ return nullptr;
+ }
+
+ fprintf(stderr, "User was not available locally, fetched from server...\n");
+ return parse_user_info(json_root, user_id, room);
+ }
+
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 directly to json. TODO: Make this work somehow?