From 4af367373f6f92b0fc1d79b2871fa942e1eb86fa Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 9 Nov 2020 00:08:53 +0100 Subject: Matrix: update user display name/avatar when updated in /sync; fix backspace search delay --- src/QuickMedia.cpp | 36 +++++------- src/SearchBar.cpp | 22 +++++--- src/plugins/Matrix.cpp | 148 +++++++++++++++++++++++++++++++------------------ 3 files changed, 121 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 0ec8d1d..fdaf3d1 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -657,8 +657,6 @@ namespace QuickMedia { } } else if(handle_searchbar) { assert(search_bar); - if(event.type == sf::Event::TextEntered) - search_bar->onTextEntered(event.text.unicode); search_bar->on_event(event); } } @@ -1126,8 +1124,6 @@ namespace QuickMedia { } if(tabs[selected_tab].search_bar) { - if(event.type == sf::Event::TextEntered) - tabs[selected_tab].search_bar->onTextEntered(event.text.unicode); tabs[selected_tab].search_bar->on_event(event); } @@ -2988,8 +2984,6 @@ namespace QuickMedia { redraw = true; } else if(event.type == sf::Event::GainedFocus) { redraw = true; - } else if(event.type == sf::Event::TextEntered) { - inputs[focused_input]->onTextEntered(event.text.unicode); } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Tab) { for(int i = 0; i < num_inputs; ++i) { inputs[i]->caret_visible = false; @@ -3047,9 +3041,9 @@ namespace QuickMedia { static const sf::Vector2i CHAT_MESSAGE_THUMBNAIL_MAX_SIZE(600, 337); - static std::shared_ptr message_to_body_item(Message *message, UserInfo *me) { + static std::shared_ptr message_to_body_item(RoomData *room, Message *message, const std::string &my_display_name, const std::string &my_user_id) { auto body_item = BodyItem::create(""); - body_item->set_author(message->user->display_name); + body_item->set_author(room->get_user_display_name(message->user)); body_item->set_description(message_get_body_remove_formatting(message)); body_item->set_timestamp(message->timestamp); if(!message->thumbnail_url.empty()) { @@ -3059,7 +3053,7 @@ namespace QuickMedia { body_item->thumbnail_url = message->url; body_item->thumbnail_size = message->thumbnail_size; } else { - body_item->thumbnail_url = message->user->avatar_url; + body_item->thumbnail_url = room->get_user_avatar_url(message->user); body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE; // if construct is not configured to use ImageMagic then it wont give thumbnails of size 32x32 even when requested and the spec says that the server SHOULD do that body_item->thumbnail_size = sf::Vector2i(32, 32); @@ -3070,15 +3064,15 @@ namespace QuickMedia { body_item->userdata = (void*)message; // Note: message has to be valid as long as body_item is used! if(message->related_event_type == RelatedEventType::REDACTION || message->related_event_type == RelatedEventType::EDIT) body_item->visible = false; - if(me && (message_contains_user_mention(message->body, me->display_name) || message_contains_user_mention(message->body, me->user_id))) + if(message_contains_user_mention(message->body, my_display_name) || message_contains_user_mention(message->body, my_user_id)) body_item->set_description_color(sf::Color(255, 100, 100)); return body_item; } - static BodyItems messages_to_body_items(const Messages &messages, UserInfo *me) { + static BodyItems messages_to_body_items(RoomData *room, const Messages &messages, const std::string &my_display_name, const std::string &my_user_id) { BodyItems result_items(messages.size()); for(size_t i = 0; i < messages.size(); ++i) { - result_items[i] = message_to_body_item(messages[i].get(), me); + result_items[i] = message_to_body_item(room, messages[i].get(), my_display_name, my_user_id); } return result_items; } @@ -3190,10 +3184,10 @@ namespace QuickMedia { // TODO: What if these never end up referencing events? clean up automatically after a while? std::unordered_map unreferenced_event_by_room; - auto set_body_as_deleted = [](Message *message, BodyItem *body_item) { + auto set_body_as_deleted = [¤t_room](Message *message, BodyItem *body_item) { body_item->embedded_item = nullptr; body_item->embedded_item_status = FetchStatus::NONE; - body_item->thumbnail_url = message->user->avatar_url; + body_item->thumbnail_url = current_room->get_user_avatar_url(message->user); body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE; body_item->set_description_color(sf::Color::White); body_item->thumbnail_size = sf::Vector2i(32, 32); @@ -3306,7 +3300,8 @@ namespace QuickMedia { for(auto &message : all_messages) { fetched_messages_set.insert(message->event_id); } - tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(all_messages, matrix->get_me(current_room).get())); + auto me = matrix->get_me(current_room); + tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(current_room, all_messages, current_room->get_user_display_name(me), me->user_id)); modify_related_messages_in_current_room(all_messages); tabs[MESSAGES_TAB_INDEX].body->select_last_item(); @@ -3577,7 +3572,7 @@ namespace QuickMedia { } }; - auto add_new_messages_to_current_room = [this, &tabs, &selected_tab, ¤t_room](Messages &messages) { + auto add_new_messages_to_current_room = [&me, &tabs, &selected_tab, ¤t_room](Messages &messages) { if(messages.empty()) return; @@ -3587,7 +3582,7 @@ namespace QuickMedia { scroll_to_end = true; BodyItem *selected_item = tabs[MESSAGES_TAB_INDEX].body->get_selected(); - tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(messages, matrix->get_me(current_room).get())); + tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(current_room, messages, current_room->get_user_display_name(me), me->user_id)); if(selected_item && !scroll_to_end) { int selected_item_index = tabs[MESSAGES_TAB_INDEX].body->get_index_by_body_item(selected_item); if(selected_item_index != -1) @@ -3896,7 +3891,6 @@ namespace QuickMedia { if((chat_state == ChatState::TYPING_MESSAGE || chat_state == ChatState::REPLYING || chat_state == ChatState::EDITING) && selected_tab == MESSAGES_TAB_INDEX && !frame_skip_text_entry) { frame_skip_text_entry = false; if(event.type == sf::Event::TextEntered) { - //chat_input.onTextEntered(event.text.unicode); // TODO: Also show typing event when ctrl+v pasting? if(event.text.unicode != 13) { // Return key start_typing_timer.restart(); @@ -4094,7 +4088,7 @@ namespace QuickMedia { size_t num_new_messages = new_messages.size(); if(num_new_messages > 0) { BodyItem *selected_item = tabs[MESSAGES_TAB_INDEX].body->get_selected(); - BodyItems new_body_items = messages_to_body_items(new_messages, matrix->get_me(current_room).get()); + BodyItems new_body_items = messages_to_body_items(current_room, new_messages, current_room->get_user_display_name(me), me->user_id); size_t num_new_body_items = new_body_items.size(); tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(std::move(new_body_items)); if(selected_item) { @@ -4124,7 +4118,7 @@ namespace QuickMedia { if(fetch_message_tab == PINNED_TAB_INDEX) { PinnedEventData *event_data = static_cast(fetch_body_item->userdata); if(message) { - *fetch_body_item = *message_to_body_item(message.get(), matrix->get_me(current_room).get()); + *fetch_body_item = *message_to_body_item(current_room, message.get(), current_room->get_user_display_name(me), me->user_id); event_data->status = FetchStatus::FINISHED_LOADING; event_data->message = message.get(); fetch_body_item->userdata = event_data; @@ -4134,7 +4128,7 @@ namespace QuickMedia { } } else if(fetch_message_tab == MESSAGES_TAB_INDEX) { if(message) { - fetch_body_item->embedded_item = message_to_body_item(message.get(), matrix->get_me(current_room).get()); + fetch_body_item->embedded_item = message_to_body_item(current_room, message.get(), current_room->get_user_display_name(me), me->user_id); fetch_body_item->embedded_item_status = FetchStatus::FINISHED_LOADING; } else { fetch_body_item->embedded_item_status = FetchStatus::FAILED_TO_LOAD; diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp index 0c72805..dea9951 100644 --- a/src/SearchBar.cpp +++ b/src/SearchBar.cpp @@ -37,7 +37,7 @@ namespace QuickMedia { needs_update(true), input_masked(input_masked), typing(false), - backspace_seq_count(0), + backspace_pressed(false), vertical_pos(0.0f) { text.setFillColor(text_placeholder_color); @@ -88,15 +88,20 @@ namespace QuickMedia { } void SearchBar::on_event(sf::Event &event) { - if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::V && event.key.control) { + if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Backspace) + backspace_pressed = true; + else if(event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Backspace) + backspace_pressed = false; + if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::V && event.key.control) append_text(sf::Clipboard::getString()); - } + if(event.type == sf::Event::TextEntered) + onTextEntered(event.text.unicode); } void SearchBar::update() { sf::Int32 elapsed_time = time_since_search_update.getElapsedTime().asMilliseconds(); int timeout = text_autosearch_delay; - if(backspace_seq_count == 1) + if(backspace_pressed) timeout = 750; if(updated_search && elapsed_time >= timeout) { updated_search = false; @@ -125,7 +130,7 @@ namespace QuickMedia { draw_logo = false; } - float font_height = text.getLocalBounds().height + 12.0f; + float font_height = text.getCharacterSize() + 7.0f; float rect_height = std::floor(font_height + background_margin_vertical * 2.0f); float offset_x = padding_horizontal; @@ -177,11 +182,10 @@ namespace QuickMedia { } updated_search = true; updated_autocomplete = true; - ++backspace_seq_count; time_since_search_update.restart(); } } else if(codepoint == 13) { // Return - backspace_seq_count = 0; + backspace_pressed = false; if(onTextSubmitCallback) { auto u8 = text.getString().toUtf8(); std::string *u8_str = (std::string*)&u8; @@ -205,7 +209,7 @@ namespace QuickMedia { needs_update = true; updated_search = false; updated_autocomplete = false; - backspace_seq_count = 0; + backspace_pressed = false; } void SearchBar::append_text(const std::string &text_to_add) { @@ -231,7 +235,7 @@ namespace QuickMedia { updated_search = true; updated_autocomplete = true; time_since_search_update.restart(); - backspace_seq_count = 0; + backspace_pressed = false; if(str[str.getSize() - 1] == '\n') needs_update = true; } 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 RoomData::get_user_by_id(const std::string &user_id) { std::lock_guard 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 &user) { + std::string RoomData::get_user_read_marker(const std::shared_ptr &user) { std::lock_guard lock(user_mutex); return user->read_marker_event_id; } + std::string RoomData::get_user_display_name(const std::shared_ptr &user) { + std::lock_guard lock(user_mutex); + return user->display_name; + } + + std::string RoomData::get_user_avatar_url(const std::shared_ptr &user) { + std::lock_guard lock(user_mutex); + return user->avatar_url; + } + + void RoomData::set_user_display_name(std::shared_ptr &user, std::string display_name) { + std::lock_guard 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 &user, std::string avatar_url) { + std::lock_guard lock(user_mutex); + user->avatar_url = std::move(avatar_url); + } + void RoomData::prepend_messages_reverse(const std::vector> &new_messages) { std::lock_guard 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(); - 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(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> 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 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> &user_info, const std::string &fallback_user_id) { + static std::string combine_user_display_names_for_room_name(std::vector> &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(); - 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(room, user_id); room->add_user(user_info); return user_info; #endif -- cgit v1.2.3