From 4aec31515ff6f61f41dfd66551a3fce44f243535 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 20 Mar 2021 07:06:06 +0100 Subject: More work on touch (behind QM_ENABLE_TOUCH=1 environment variable), save thumbnails with their size so using a different scaling will update thumbnails to the same scale --- TODO | 1 - include/Body.hpp | 8 +++ src/AsyncImageLoader.cpp | 2 + src/Body.cpp | 137 ++++++++++++++++++++++++++++++----------------- src/QuickMedia.cpp | 43 +++++++++++---- src/plugins/Matrix.cpp | 15 ++++-- 6 files changed, 142 insertions(+), 64 deletions(-) diff --git a/TODO b/TODO index 5685dc6..5798914 100644 --- a/TODO +++ b/TODO @@ -47,7 +47,6 @@ Cleanup keybindings. Some require ctrl, some dont. Add room topic beside room name in matrix (in messages tab). Add /me to matrix, emoji, reactions... Set the icon of the window to be the icon of the plugin. Nice for KDE, GNOME, etc with titlebars. -Set a minimum wrap size for text. We dont want one line of text to fully fill the window vertically when the window size width is small. Its better to cut off the text and add eclipses. If --no-audio is used then music should be played with a lightweight music player instead. MPV is heavy even for music (60mb RAM). Maybe use sfml audio functions? Optimize startup time. Update 4chan thread in real time, just like 4chan-x. diff --git a/include/Body.hpp b/include/Body.hpp index ac5853d..869ce0b 100644 --- a/include/Body.hpp +++ b/include/Body.hpp @@ -249,6 +249,7 @@ namespace QuickMedia { sf::Vector2i thumbnail_max_size; sf::Color line_separator_color; BodyItemRenderCallback body_item_render_callback; + std::function body_item_select_callback; sf::Shader *thumbnail_mask_shader; AttachSide attach_side = AttachSide::TOP; private: @@ -280,12 +281,19 @@ namespace QuickMedia { bool items_cut_off = false; float offset_to_top = 0.0f; float offset_to_bottom = 0.0f; + bool experimental_use_touch = false; bool mouse_state_set = false; bool mouse_left_pressed = false; + bool mouse_left_clicked = false; + sf::Vector2f mouse_click_pos; + sf::Vector2f mouse_release_pos; + double mouse_press_pixels_moved_abs; sf::Vector2f mouse_pos; sf::Vector2f prev_mouse_pos; sf::Vector2i mouse_pos_raw; sf::Vector2f mouse_scroll_accel; + sf::Vector2f body_pos; + sf::Vector2f body_size; float selected_item_height = 0.0f; float selected_scrolled = 0.0f; //float scroll_y = 0.0f; diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp index d0a67c4..9792781 100644 --- a/src/AsyncImageLoader.cpp +++ b/src/AsyncImageLoader.cpp @@ -164,6 +164,8 @@ namespace QuickMedia { SHA256 sha256; sha256.add(url.data(), url.size()); Path thumbnail_path = get_cache_dir().join("thumbnails").join(sha256.getHash()); + if(resize_target_size.x != 0 && resize_target_size.y != 0) + thumbnail_path.append("_" + std::to_string(resize_target_size.x) + "x" + std::to_string(resize_target_size.y)); if(get_file_type(thumbnail_path) == FileType::REGULAR) { thumbnail_data->loading_state = LoadingState::LOADING; image_load_queue.push({ url, thumbnail_path, local, thumbnail_data, resize_target_size }); diff --git a/src/Body.cpp b/src/Body.cpp index 293f516..667232e 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -136,6 +136,10 @@ namespace QuickMedia { item_background.setFillColor(sf::Color(55, 60, 68)); sf::Vector2f loading_icon_size(loading_icon.getTexture()->getSize().x, loading_icon.getTexture()->getSize().y); loading_icon.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f); + const char *qm_enable_touch = getenv("QM_ENABLE_TOUCH"); + if(qm_enable_touch && qm_enable_touch[0] == '1') { + experimental_use_touch = true; + } } // TODO: Make this work with wraparound enabled? @@ -372,35 +376,48 @@ namespace QuickMedia { } bool Body::on_event(const sf::RenderWindow &window, const sf::Event &event) { - #if 0 + if(!experimental_use_touch) + return false; + if(!mouse_state_set) { mouse_state_set = true; mouse_left_pressed = sf::Mouse::isButtonPressed(sf::Mouse::Left); - if(mouse_left_pressed) { - mouse_pos_raw = sf::Mouse::getPosition(window); - mouse_pos = sf::Vector2f(mouse_pos_raw.x, mouse_pos_raw.y); - prev_mouse_pos = mouse_pos; - return true; + if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { + auto mpos = sf::Mouse::getPosition(window); + if(sf::FloatRect(body_pos, body_size).contains(sf::Vector2f(mpos.x, mpos.y))) { + mouse_left_pressed = true; + mouse_pos_raw = sf::Mouse::getPosition(window); + mouse_pos = sf::Vector2f(mouse_pos_raw.x, mouse_pos_raw.y); + prev_mouse_pos = mouse_pos; + mouse_click_pos = mouse_pos; + mouse_press_pixels_moved_abs = 0.0; + return true; + } } } - if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left && !mouse_left_pressed) { + if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left && !mouse_left_pressed && sf::FloatRect(body_pos, body_size).contains(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) { mouse_left_pressed = true; mouse_pos_raw.x = event.mouseButton.x; mouse_pos_raw.y = event.mouseButton.y; mouse_pos = sf::Vector2f(mouse_pos_raw.x, mouse_pos_raw.y); prev_mouse_pos = mouse_pos; + mouse_click_pos = mouse_pos; + mouse_press_pixels_moved_abs = 0.0; return true; } else if(event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left && mouse_left_pressed) { mouse_left_pressed = false; + mouse_left_clicked = true; + mouse_release_pos = sf::Vector2f(event.mouseButton.x, event.mouseButton.y); return true; } else if(event.type == sf::Event::MouseMoved && mouse_left_pressed) { + sf::Vector2i mouse_pos_diff(event.mouseMove.x - mouse_pos_raw.x, event.mouseMove.y - mouse_pos_raw.y); + mouse_press_pixels_moved_abs += std::sqrt(mouse_pos_diff.x*mouse_pos_diff.x + mouse_pos_diff.y*mouse_pos_diff.y); mouse_pos_raw.x = event.mouseMove.x; mouse_pos_raw.y = event.mouseMove.y; return true; } - #endif return false; } @@ -415,51 +432,60 @@ namespace QuickMedia { sf::Vector2f scissor_size = size; const float start_y = pos.y; + body_pos = pos; + body_size = size; + elapsed_time_sec = draw_timer.getElapsedTime().asSeconds(); -#if 0 - float frame_time = frame_timer.restart().asSeconds(); - if(frame_time > 2.0f) - frame_time = 2.0f; - - const sf::Vector2f mouse_pos_diff(mouse_pos_raw.x - mouse_pos.x, mouse_pos_raw.y - mouse_pos.y); - const float move_speed = 25.0f; - mouse_pos.x += (mouse_pos_diff.x * frame_time * move_speed); - mouse_pos.y += (mouse_pos_diff.y * frame_time * move_speed); - - sf::Vector2f mouse_smooth_diff(mouse_pos.x - prev_mouse_pos.x, mouse_pos.y - prev_mouse_pos.y); - prev_mouse_pos = mouse_pos; - - if(mouse_left_pressed) { - selected_scrolled += mouse_smooth_diff.y; - page_scroll += mouse_smooth_diff.y; - mouse_scroll_accel = mouse_smooth_diff; - } else { - selected_scrolled += mouse_scroll_accel.y; - page_scroll += mouse_scroll_accel.y; - const float scroll_deaccel = 1.02f; - double deaccel = scroll_deaccel * (1.0 + frame_time); - if(deaccel < 0.0001) - deaccel = 1.0; - - mouse_scroll_accel.x /= deaccel; - if(fabs(mouse_scroll_accel.x) < 0.0001) - mouse_scroll_accel.x = 0.0; - - mouse_scroll_accel.y /= deaccel; - if(fabs(mouse_scroll_accel.y) < 0.0001) - mouse_scroll_accel.y = 0.0; - } - if(selected_item != -1) { - if(selected_scrolled <= -selected_item_height) { - selected_scrolled += selected_item_height; - select_next_item(false); - } else if(selected_scrolled >= selected_item_height) { - selected_scrolled -= selected_item_height; - select_previous_item(false); + if(experimental_use_touch) { + float frame_time = frame_timer.restart().asSeconds(); + if(frame_time > 2.0f) + frame_time = 2.0f; + + const sf::Vector2f mouse_pos_diff(mouse_pos_raw.x - mouse_pos.x, mouse_pos_raw.y - mouse_pos.y); + const float move_speed = 25.0f; + mouse_pos.x += (mouse_pos_diff.x * frame_time * move_speed); + mouse_pos.y += (mouse_pos_diff.y * frame_time * move_speed); + + sf::Vector2f mouse_smooth_diff(mouse_pos.x - prev_mouse_pos.x, mouse_pos.y - prev_mouse_pos.y); + prev_mouse_pos = mouse_pos; + + if(items_cut_off) { + if(mouse_left_pressed) { + selected_scrolled += mouse_smooth_diff.y; + page_scroll += mouse_smooth_diff.y; + mouse_scroll_accel = mouse_smooth_diff; + } else { + selected_scrolled += mouse_scroll_accel.y; + page_scroll += mouse_scroll_accel.y; + } + } + + if(!mouse_left_pressed) { + const float scroll_deaccel = 1.02f; + double deaccel = scroll_deaccel * (1.0 + frame_time); + if(deaccel < 0.0001) + deaccel = 1.0; + + mouse_scroll_accel.x /= deaccel; + if(fabs(mouse_scroll_accel.x) < 0.0001) + mouse_scroll_accel.x = 0.0; + + mouse_scroll_accel.y /= deaccel; + if(fabs(mouse_scroll_accel.y) < 0.0001) + mouse_scroll_accel.y = 0.0; + } + + if(selected_item != -1) { + if(selected_scrolled <= -selected_item_height) { + selected_scrolled += selected_item_height; + select_next_item(false); + } else if(selected_scrolled >= selected_item_height) { + selected_scrolled -= selected_item_height; + select_previous_item(false); + } } } -#endif //item_background.setFillColor(front_color); //item_background.setOutlineThickness(1.0f); @@ -483,6 +509,7 @@ namespace QuickMedia { items_cut_off = false; offset_to_top = 0.0f; offset_to_bottom = 0.0f; + mouse_left_clicked = false; return; } @@ -559,6 +586,7 @@ namespace QuickMedia { page_scroll = 0.0f; } + page_scroll = std::floor(page_scroll); pos.y += page_scroll; bool last_item_fully_visible_set = false; @@ -650,6 +678,8 @@ namespace QuickMedia { if(!items_cut_off_set) items_cut_off = false; + mouse_left_clicked = false; + for(auto it = item_thumbnail_textures.begin(); it != item_thumbnail_textures.end();) { if(!it->second->referenced) it = item_thumbnail_textures.erase(it); @@ -813,6 +843,15 @@ namespace QuickMedia { item_pos.x = std::floor(pos.x); item_pos.y = std::floor(pos.y); + if(body_item_select_callback && mouse_left_clicked) { + sf::FloatRect item_box(pos, sf::Vector2f(size.x, item_height)); + // TODO: Scale mouse_press_pixels_moved_abs with monitor PPI instead of using get_ui_scale() + if(item_box.contains(mouse_click_pos) && item_box.contains(mouse_release_pos) && mouse_press_pixels_moved_abs <= 50.0 * get_ui_scale()) { + set_selected_item(item_index, false); + body_item_select_callback(item); + } + } + item_separator.setSize(sf::Vector2f(std::max(0.0f, size.x - 20.0f), 1.0f)); item_separator.setPosition(item_pos + sf::Vector2f(10.0f, std::floor(item_height + spacing_y * 0.5f))); window.draw(item_separator); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index d54229f..61b2d1b 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -53,6 +53,7 @@ static const sf::Color tab_selected_color(55, 60, 68); static const float tab_margin_x = std::floor(10.0f * QuickMedia::get_ui_scale()); static int FPS_IDLE = 2; static const double IDLE_TIMEOUT_SEC = 2.0; +static const sf::Vector2i AVATAR_THUMBNAIL_SIZE(std::floor(32 * QuickMedia::get_ui_scale()), std::floor(32 * QuickMedia::get_ui_scale())); // Prevent writing to broken pipe from exiting the program static void sigpipe_handler(int) { @@ -1100,7 +1101,9 @@ namespace QuickMedia { window_size.x = window_size_u.x; window_size.y = window_size_u.y; - auto submit_handler = [this, &after_submit_handler, &json_chapters, &tabs, &tab_associated_data, &selected_tab, &loop_running, &redraw]() { + std::function submit_handler; + + submit_handler = [this, &submit_handler, &after_submit_handler, &json_chapters, &tabs, &tab_associated_data, &selected_tab, &loop_running, &redraw]() { BodyItem *selected_item = tabs[selected_tab].body->get_selected(); if(!selected_item) return; @@ -1195,6 +1198,9 @@ namespace QuickMedia { break; current_chat_room = matrix->get_room_by_id(selected_item->url); } + tabs[selected_tab].body->body_item_select_callback = [&submit_handler](BodyItem *body_item) { + submit_handler(); + }; //select_body_item_by_room(tabs[selected_tab].body.get(), current_chat_room); current_chat_room = nullptr; } else { @@ -1213,6 +1219,10 @@ namespace QuickMedia { for(size_t i = 0; i < tabs.size(); ++i) { Tab &tab = tabs[i]; + tab.body->body_item_select_callback = [&submit_handler](BodyItem *body_item) { + submit_handler(); + }; + TabAssociatedData &associated_data = tab_associated_data[i]; if(!tab.search_bar) continue; @@ -1263,6 +1273,7 @@ namespace QuickMedia { window_size.y = event.size.height; sf::FloatRect visible_area(0, 0, window_size.x, window_size.y); window.setView(sf::View(visible_area)); + idle_active_handler(); } if(tabs[selected_tab].search_bar) { @@ -2767,6 +2778,7 @@ namespace QuickMedia { window_size.y = event.size.height; sf::FloatRect visible_area(0, 0, window_size.x, window_size.y); window.setView(sf::View(visible_area)); + idle_active_handler(); } if(event.type == sf::Event::Resized || event.type == sf::Event::GainedFocus) @@ -3122,6 +3134,7 @@ namespace QuickMedia { sf::FloatRect visible_area(0, 0, window_size.x, window_size.y); window.setView(sf::View(visible_area)); redraw = true; + idle_active_handler(); } else if(event.type == sf::Event::GainedFocus) { redraw = true; } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Tab) { @@ -3178,7 +3191,7 @@ namespace QuickMedia { 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); + body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE; } // TODO: Show image thumbnail inline instead of url to image and showing it as the thumbnail of the body item body_item->url = message->url; @@ -3345,7 +3358,7 @@ namespace QuickMedia { } body_item->set_description("Message deleted"); body_item->set_description_color(sf::Color::White); - body_item->thumbnail_size = sf::Vector2i(32, 32); + body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE; body_item->url.clear(); }; @@ -4170,7 +4183,7 @@ namespace QuickMedia { pinned_body_item->thumbnail_url = user_avatar_url; pinned_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 - pinned_body_item->thumbnail_size = sf::Vector2i(32, 32); + pinned_body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE; } } }; @@ -4190,7 +4203,7 @@ namespace QuickMedia { message_body_items->thumbnail_url = user_avatar_url; message_body_items->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 - message_body_items->thumbnail_size = sf::Vector2i(32, 32); + message_body_items->thumbnail_size = AVATAR_THUMBNAIL_SIZE; } } }; @@ -4209,7 +4222,7 @@ namespace QuickMedia { pinned_body_item->thumbnail_url = current_room->get_user_avatar_url(message->user); pinned_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 - pinned_body_item->thumbnail_size = sf::Vector2i(32, 32); + pinned_body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE; } } }; @@ -4227,7 +4240,7 @@ namespace QuickMedia { message_body_items->thumbnail_url = current_room->get_user_avatar_url(message->user); message_body_items->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 - message_body_items->thumbnail_size = sf::Vector2i(32, 32); + message_body_items->thumbnail_size = AVATAR_THUMBNAIL_SIZE; } } }; @@ -4280,9 +4293,13 @@ namespace QuickMedia { float tab_shade_height = 0.0f; bool frame_skip_text_entry = false; + room_tabs[room_selected_tab].body->body_item_select_callback = [&move_room](BodyItem *body_item) { + move_room = true; + }; + SyncData sync_data; - while (current_page == PageType::CHAT && window.isOpen()) { + while (current_page == PageType::CHAT && window.isOpen() && !move_room) { sf::Int32 frame_time_ms = frame_timer.restart().asMilliseconds(); while (window.pollEvent(event)) { if(chat_state == ChatState::URL_SELECTION) { @@ -4296,6 +4313,9 @@ namespace QuickMedia { base_event_handler(event, PageType::EXIT, tabs[selected_tab].body.get(), nullptr, false, false); event_idle_handler(event); + if(draw_room_list) + room_tabs[room_selected_tab].body->on_event(window, event); + if(event.type == sf::Event::KeyPressed && event.key.control && event.key.alt && (chat_state == ChatState::NAVIGATING || chat_state == ChatState::URL_SELECTION)) { if(event.key.code == sf::Keyboard::Up || (event.key.control && event.key.code == sf::Keyboard::K)) { room_tabs[room_selected_tab].body->select_previous_item(); @@ -4336,7 +4356,10 @@ namespace QuickMedia { redraw = true; } else if(event.type == sf::Event::LostFocus) { is_window_focused = false; - } else if(event.type == sf::Event::Resized || event.type == sf::Event::GainedFocus) { + } else if(event.type == sf::Event::Resized) { + redraw = true; + idle_active_handler(); + } else if(event.type == sf::Event::GainedFocus) { redraw = true; } else if(event.type == sf::Event::KeyPressed && chat_state == ChatState::NAVIGATING) { if(event.key.code == sf::Keyboard::Up || event.key.code == sf::Keyboard::PageUp || event.key.code == sf::Keyboard::Home || (event.key.control && event.key.code == sf::Keyboard::K)) { @@ -4631,7 +4654,7 @@ namespace QuickMedia { } if(current_room && current_room->body_item && room_avatar_thumbnail_data->loading_state == LoadingState::NOT_LOADED) - AsyncImageLoader::get_instance().load_thumbnail(current_room->body_item->thumbnail_url, false, sf::Vector2i(32, 32), use_tor, room_avatar_thumbnail_data); + AsyncImageLoader::get_instance().load_thumbnail(current_room->body_item->thumbnail_url, false, AVATAR_THUMBNAIL_SIZE, use_tor, room_avatar_thumbnail_data); if(room_avatar_thumbnail_data->loading_state == LoadingState::FINISHED_LOADING && room_avatar_thumbnail_data->image->getSize().x > 0 && room_avatar_thumbnail_data->image->getSize().y > 0) { if(!room_avatar_thumbnail_data->texture.loadFromImage(*room_avatar_thumbnail_data->image)) diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index aa6de40..263a948 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -6,11 +6,13 @@ #include "../../include/Program.hpp" #include "../../include/base64_url.hpp" #include "../../include/Json.hpp" +#include "../../include/Utils.hpp" #include #include #include #include #include +#include #include #include #include "../../include/QuickMedia.hpp" @@ -1602,6 +1604,11 @@ namespace QuickMedia { return media_url.substr(start, end - start); } + static std::string get_thumbnail_url(const std::string &homeserver, const std::string &mxc_id) { + std::string size = std::to_string(int(32 * get_ui_scale())); + return homeserver + "/_matrix/media/r0/thumbnail/" + mxc_id + "?width=" + size + "&height=" + size + "&method=crop"; + } + std::shared_ptr Matrix::parse_user_info(const rapidjson::Value &json, const std::string &user_id, RoomData *room_data) { assert(json.IsObject()); std::string avatar_url_str; @@ -1614,7 +1621,7 @@ namespace QuickMedia { 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) + avatar_url = get_thumbnail_url(homeserver, avatar_url); // 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); @@ -1983,7 +1990,7 @@ namespace QuickMedia { 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) + new_avatar_url_str = get_thumbnail_url(homeserver, new_avatar_url_str); // 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() || new_avatar_url_json.GetStringLength() == 0) && prev_avatar_url_json.IsString()) { body = user_display_name + " removed their profile picture"; @@ -2200,7 +2207,7 @@ namespace QuickMedia { continue; std::string url_json_str = url_json.GetString() + 6; - room_data->set_avatar_url(homeserver + "/_matrix/media/r0/thumbnail/" + thumbnail_url_extract_media_id(url_json_str) + "?width=32&height=32&method=crop"); + room_data->set_avatar_url(get_thumbnail_url(homeserver, thumbnail_url_extract_media_id(url_json_str))); room_data->avatar_is_fallback = false; } } @@ -3742,7 +3749,7 @@ namespace QuickMedia { if(avatar_url_json.IsString()) avatar_url = std::string(avatar_url_json.GetString(), avatar_url_json.GetStringLength()); if(!avatar_url.empty()) - avatar_url = homeserver + "/_matrix/media/r0/thumbnail/" + thumbnail_url_extract_media_id(avatar_url) + "?width=32&height=32&method=crop"; // TODO: Remove the constant strings around to reduce memory usage (6.3mb) + avatar_url = get_thumbnail_url(homeserver, thumbnail_url_extract_media_id(avatar_url)); // TODO: Remove the constant strings around to reduce memory usage (6.3mb) room->set_user_avatar_url(user, std::move(avatar_url)); room->set_user_display_name(user, std::move(display_name)); } -- cgit v1.2.3