From 5a2bb738b05253287438df9f1a0bdb95fea92dd9 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 23 Jul 2021 12:52:59 +0200 Subject: Matrix: fix crash when pinned message is removed quickly --- src/Body.cpp | 32 ++++++++++++++++---------------- src/QuickMedia.cpp | 26 ++++++++++++++------------ src/plugins/Youtube.cpp | 7 ++++++- 3 files changed, 36 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/Body.cpp b/src/Body.cpp index b11cb51..10911e4 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -922,10 +922,10 @@ namespace QuickMedia { return -1; } - void Body::draw_item(sf::RenderWindow &window, BodyItem *item, sf::Vector2f pos, sf::Vector2f size, bool include_embedded_item, bool is_embedded) { + void Body::draw_item(sf::RenderWindow &window, std::shared_ptr &item, sf::Vector2f pos, sf::Vector2f size, bool include_embedded_item, bool is_embedded) { // TODO: What about when |card_view| is used? item->keep_alive_frames = 3; - get_item_height(item, size.x, true, false, false, -1); + get_item_height(item.get(), size.x, true, false, false, -1); draw_item(window, item, pos, size, size.y + body_spacing[body_theme].spacing_y, -1, Json::Value::nullSingleton(), include_embedded_item); } @@ -1001,7 +1001,7 @@ namespace QuickMedia { // TODO: Improve performance. Skip items that are obviously not visible or anywhere near the body. Limit loop to 100-200 items around the selected item while(index != -1) { - BodyItem *item = items[index].get(); + std::shared_ptr &item = items[index]; assert(item->visible); int prev_index; @@ -1013,11 +1013,11 @@ namespace QuickMedia { prev_body_item = items[prev_index].get(); } - const bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item, item); + const bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item, item.get()); if(attach_side == AttachSide::TOP && merge_with_previous) pos.y -= body_spacing[body_theme].spacing_y; - get_item_height(item, size.x, false, true, merge_with_previous, index); + get_item_height(item.get(), size.x, false, true, merge_with_previous, index); float top_y; if(attach_side == AttachSide::TOP) @@ -1039,7 +1039,7 @@ namespace QuickMedia { const bool is_item_visible_in_body = top_y + item->loaded_height >= 0.0f && top_y <= size.y; if(is_item_visible_in_body || index == selected_item) { - get_item_height(item, size.x, true, true, merge_with_previous, index); + get_item_height(item.get(), size.x, true, true, merge_with_previous, index); if(attach_side == AttachSide::BOTTOM) pos.y -= (item->loaded_height + body_spacing[body_theme].spacing_y); //page_scroll += add_height; @@ -1075,7 +1075,7 @@ namespace QuickMedia { pos.y -= (item->loaded_height + body_spacing[body_theme].spacing_y); if(item->keep_alive_frames == 0) { - clear_body_item_cache(item); + clear_body_item_cache(item.get()); // TODO: Make sure the embedded item is not referencing another item in the |items| list if(item->embedded_item) clear_body_item_cache(item->embedded_item.get()); @@ -1088,7 +1088,7 @@ namespace QuickMedia { pos.y += body_spacing[body_theme].spacing_y; if(attach_side == AttachSide::TOP) { - prev_body_item = item; + prev_body_item = item.get(); index = get_next_visible_item(index); } else { index = prev_index; @@ -1136,9 +1136,9 @@ namespace QuickMedia { sf::Vector2f pos_offset(space_left_column_each, page_scroll); while(item_index < num_items) { - BodyItem *item = items[item_index].get(); + std::shared_ptr &item = items[item_index]; - get_item_height(item, card_max_image_size.x, false, false, false, item_index); + get_item_height(item.get(), card_max_image_size.x, false, false, false, item_index); int item_height = item->loaded_height; item_height = std::min(card_height, item_height + ((draw_thumbnails && !item->thumbnail_url.empty()) ? card_image_text_padding : 0) + card_padding_y * 2 + 5); row_max_height = std::max(row_max_height, item_height); @@ -1164,12 +1164,12 @@ namespace QuickMedia { if(body_item_render_callback) body_item_render_callback(item); - sf::Vector2i thumbnail_size = get_item_thumbnail_size(item); + sf::Vector2i thumbnail_size = get_item_thumbnail_size(item.get()); std::shared_ptr item_thumbnail; if(draw_thumbnails && !item->thumbnail_url.empty()) item_thumbnail = AsyncImageLoader::get_instance().get_thumbnail(item->thumbnail_url, item->thumbnail_is_local, thumbnail_size); - get_item_height(item, card_max_image_size.x, true, false, false, item_index); + get_item_height(item.get(), card_max_image_size.x, true, false, false, item_index); item_height = item->loaded_height; item_height = std::min(card_height, item_height + (item_thumbnail ? card_image_text_padding : 0) + card_padding_y * 2 + 5); row_max_height = std::max(row_max_height, item_height); @@ -1274,7 +1274,7 @@ namespace QuickMedia { handle_item_render(pos + pos_offset, card_width, item_height, item_index); if(item->keep_alive_frames == 0) { - clear_body_item_cache(item); + clear_body_item_cache(item.get()); // TODO: Make sure the embedded item is not referencing another item in the |items| list if(item->embedded_item) clear_body_item_cache(item->embedded_item.get()); @@ -1307,8 +1307,8 @@ namespace QuickMedia { item_background_target_size = sf::Vector2f(card_width, row_max_height); } - void Body::draw_item(sf::RenderWindow &window, BodyItem *item, const sf::Vector2f &pos, const sf::Vector2f &size, const float item_height, const int item_index, const Json::Value &content_progress, bool include_embedded_item, bool merge_with_previous) { - sf::Vector2i thumbnail_size = get_item_thumbnail_size(item); + void Body::draw_item(sf::RenderWindow &window, std::shared_ptr &item, const sf::Vector2f &pos, const sf::Vector2f &size, const float item_height, const int item_index, const Json::Value &content_progress, bool include_embedded_item, bool merge_with_previous) { + sf::Vector2i thumbnail_size = get_item_thumbnail_size(item.get()); std::shared_ptr item_thumbnail; if(draw_thumbnails && !merge_with_previous && !item->thumbnail_url.empty()) item_thumbnail = AsyncImageLoader::get_instance().get_thumbnail(item->thumbnail_url, item->thumbnail_is_local, thumbnail_size); @@ -1422,7 +1422,7 @@ namespace QuickMedia { if(item->embedded_item) { sf::Vector2f embedded_item_pos(std::floor(item_pos.x + text_offset_x + embedded_item_border_width + body_spacing[body_theme].padding_x), std::floor(item_pos.y + body_spacing[body_theme].embedded_item_padding_y + 6.0f)); sf::Vector2f embedded_item_size(embedded_item_width, embedded_item_height); - draw_item(window, item->embedded_item.get(), embedded_item_pos, embedded_item_size, false, true); + draw_item(window, item->embedded_item, embedded_item_pos, embedded_item_size, false, true); } else { embedded_item_load_text.setString(embedded_item_status_to_string(item->embedded_item_status)); embedded_item_load_text.setPosition(std::floor(item_pos.x + text_offset_x + embedded_item_border_width + body_spacing[body_theme].padding_x), std::floor(item_pos.y + embedded_item_height * 0.5f - (body_spacing[body_theme].embedded_item_font_size + 5.0f) * 0.5f + 6.0f)); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 161ea1a..dfb7770 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -5215,11 +5215,11 @@ namespace QuickMedia { AsyncTask fetch_users_future; AsyncTask fetch_message_future; Message *fetch_message = nullptr; - BodyItem *fetch_body_item = nullptr; + std::shared_ptr fetch_body_item = nullptr; int fetch_message_tab = -1; // TODO: How about instead fetching all messages we have, not only the visible ones? also fetch with multiple threads. - tabs[PINNED_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &me, &fetch_message_future, &tabs, &fetch_body_item, &fetch_message_tab, PINNED_TAB_INDEX, MESSAGES_TAB_INDEX](BodyItem *body_item) { + tabs[PINNED_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &me, &fetch_message_future, &tabs, &fetch_body_item, &fetch_message_tab, PINNED_TAB_INDEX, MESSAGES_TAB_INDEX](std::shared_ptr &body_item) { if(fetch_message_future.valid()) return; @@ -5232,7 +5232,7 @@ namespace QuickMedia { if(event_data->message->related_event_id.empty() || event_data->message->related_event_type != RelatedEventType::REPLY || (body_item->embedded_item_status != FetchStatus::NONE && body_item->embedded_item_status != FetchStatus::QUEUED_LOADING)) return; - if(load_cached_related_embedded_item(body_item, event_data->message, me, current_room, tabs[MESSAGES_TAB_INDEX].body->items)) + if(load_cached_related_embedded_item(body_item.get(), event_data->message, me, current_room, tabs[MESSAGES_TAB_INDEX].body->items)) return; std::string message_event_id = event_data->message->related_event_id; @@ -5277,7 +5277,7 @@ namespace QuickMedia { }; // TODO: How about instead fetching all messages we have, not only the visible ones? also fetch with multiple threads. - tabs[MESSAGES_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &me, &fetch_message_future, &tabs, &fetch_body_item, &fetch_message_tab, MESSAGES_TAB_INDEX](BodyItem *body_item) { + tabs[MESSAGES_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &me, &fetch_message_future, &tabs, &fetch_body_item, &fetch_message_tab, MESSAGES_TAB_INDEX](std::shared_ptr &body_item) { Message *message = static_cast(body_item->userdata); if(!message) return; @@ -5290,7 +5290,7 @@ namespace QuickMedia { return; } - if(load_cached_related_embedded_item(body_item, message, me, current_room, tabs[MESSAGES_TAB_INDEX].body->items)) + if(load_cached_related_embedded_item(body_item.get(), message, me, current_room, tabs[MESSAGES_TAB_INDEX].body->items)) return; std::string message_event_id = message->related_event_id; @@ -5356,7 +5356,7 @@ namespace QuickMedia { float prev_chat_height = chat_input.get_height(); float chat_input_height_full = 0.0f; - const float logo_padding_x = std::floor(15.0f * get_ui_scale()); + const float logo_padding_x = std::floor(10.0f * get_ui_scale()); const float chat_input_padding_x = std::floor(10.0f * get_ui_scale()); const float chat_input_padding_y = std::floor(10.0f * get_ui_scale()); @@ -6111,7 +6111,7 @@ namespace QuickMedia { update_pinned_messages_author(fetch_message->user); update_messages_author(fetch_message->user); fetch_message = nullptr; - } else if(fetch_message_result.type == FetchMessageType::MESSAGE) { + } else if(fetch_message_result.type == FetchMessageType::MESSAGE && fetch_body_item) { fprintf(stderr, "Finished fetching message: %s\n", fetch_message_result.message ? fetch_message_result.message->event_id.c_str() : "(null)"); if(fetch_message_tab == PINNED_TAB_INDEX) { PinnedEventData *event_data = static_cast(fetch_body_item->userdata); @@ -6134,6 +6134,7 @@ namespace QuickMedia { fetch_body_item->embedded_item_status = FetchStatus::FAILED_TO_LOAD; } } + fetch_body_item = nullptr; } fetch_message_tab = -1; } @@ -6232,8 +6233,9 @@ namespace QuickMedia { overlay.setFillColor(sf::Color(0, 0, 0, 240)); window.draw(overlay); - sf::Vector2f body_item_pos(body_pos.x, window_size.y - chat_input_height_full - item_height); - sf::Vector2f body_item_size(body_size.x, item_height); + const float padding_x = std::floor(10.0f * QuickMedia::get_ui_scale()); + sf::Vector2f body_item_pos(body_pos.x + padding_x, window_size.y - chat_input_height_full - item_height); + sf::Vector2f body_item_size(body_size.x - padding_x * 2.0f, item_height); sf::RectangleShape item_background(sf::Vector2f(window_size.x, body_item_size.y + chat_input_height_full + replying_to_text_height + margin)); item_background.setPosition(sf::Vector2f(0.0f, window_size.y - (body_item_size.y + chat_input_height_full + replying_to_text_height + margin))); @@ -6247,14 +6249,14 @@ namespace QuickMedia { window.draw(user_mention_background); tabs[USERS_TAB_INDEX].body->draw(window, - sf::Vector2f(body_pos.x, item_background.getPosition().y - user_mention_body_height), - sf::Vector2f(body_size.x, user_mention_body_height)); + sf::Vector2f(body_pos.x + padding_x, item_background.getPosition().y - user_mention_body_height), + sf::Vector2f(body_size.x - padding_x * 2.0f, user_mention_body_height)); } replying_to_text.setPosition(body_item_pos.x, body_item_pos.y - replying_to_text_height); window.draw(replying_to_text); - tabs[MESSAGES_TAB_INDEX].body->draw_item(window, currently_operating_on_item.get(), body_item_pos, body_item_size); + tabs[MESSAGES_TAB_INDEX].body->draw_item(window, currently_operating_on_item, body_item_pos, body_item_size); } if(selected_tab == MESSAGES_TAB_INDEX && current_room && current_room->body_item && !current_room->last_message_read && matrix->is_initial_sync_finished()) { diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp index 167b201..4544a45 100644 --- a/src/plugins/Youtube.cpp +++ b/src/plugins/Youtube.cpp @@ -2463,9 +2463,14 @@ R"END( } const std::string &url = cipher_params["url"]; - if(cipher_params.empty() || url.empty()) + if(url.empty()) return false; + if(cipher_params.empty()) { + youtube_format.url = url; + return true; + } + std::string url_decoded = url_param_decode(url); url_decoded += "&alr=yes&cver=2.20210615.01.00&cpn=" + cpn; -- cgit v1.2.3