From 48aa56227856b46d6502203f26464c05f16b6913 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 1 Oct 2020 23:27:15 +0200 Subject: Matrix: make set read marker async to fix stutter when receiving messages, also fix crash(?) when loading thumbnails that fail to load --- src/Body.cpp | 2 +- src/ImageViewer.cpp | 2 +- src/QuickMedia.cpp | 33 ++++++++++++++++++++++++--------- 3 files changed, 26 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Body.cpp b/src/Body.cpp index 673a095..6b352b3 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -470,7 +470,7 @@ namespace QuickMedia { async_image_loader.load_thumbnail(item->thumbnail_url, item->thumbnail_is_local, thumbnail_resize_target_size, program->get_current_plugin()->use_tor, item_thumbnail); } - if(item_thumbnail->loading_state == LoadingState::FINISHED_LOADING) { + if(item_thumbnail->loading_state == LoadingState::FINISHED_LOADING && item_thumbnail->image->getSize().x > 0 && item_thumbnail->image->getSize().y > 0) { if(!item_thumbnail->texture.loadFromImage(*item_thumbnail->image)) fprintf(stderr, "Warning: failed to load texture from image: %s\n", item->thumbnail_url.c_str()); item_thumbnail->image.reset(); diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp index e005337..24894fd 100644 --- a/src/ImageViewer.cpp +++ b/src/ImageViewer.cpp @@ -259,7 +259,7 @@ namespace QuickMedia { int page_i = 0; for(auto &page_data : image_data) { if(page_data) { - if(page_data->image_status == ImageStatus::LOADED) { + if(page_data->image_status == ImageStatus::LOADED && page_data->image->getSize().x > 0 && page_data->image->getSize().y > 0) { if(page_data->texture.loadFromImage(*page_data->image)) { double height_before = get_page_size(page_i).y; page_data->image_status = ImageStatus::APPLIED_TO_TEXTURE; diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 860d216..8835b1d 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -3547,6 +3547,9 @@ namespace QuickMedia { sf::Clock read_marker_timer; const sf::Int32 read_marker_timeout_ms = 3000; + std::future set_read_marker_future; + bool setting_read_marker = false; + auto launch_url = [this, &redraw](const std::string &url) mutable { if(url.empty()) return; @@ -3618,7 +3621,7 @@ namespace QuickMedia { current_page = Page::EXIT; body->clear_items(); body->reset_selected(); - } else if(event.key.code == sf::Keyboard::Left) { + } else if(event.key.code == sf::Keyboard::Left && synced) { tabs[selected_tab].body->clear_thumbnails(); selected_tab = std::max(0, selected_tab - 1); read_marker_timer.restart(); @@ -3628,7 +3631,7 @@ namespace QuickMedia { typing = false; typing_futures.push_back(std::async(typing_async_func, false, current_room_id)); } - } else if(event.key.code == sf::Keyboard::Right) { + } else if(event.key.code == sf::Keyboard::Right && synced) { tabs[selected_tab].body->clear_thumbnails(); selected_tab = std::min((int)tabs.size() - 1, selected_tab + 1); read_marker_timer.restart(); @@ -3881,7 +3884,7 @@ namespace QuickMedia { if(current_room_body_data && room_avatar_thumbnail_data->loading_state == LoadingState::NOT_LOADED) async_image_loader.load_thumbnail(current_room_body_data->body_item->thumbnail_url, false, sf::Vector2i(), use_tor, room_avatar_thumbnail_data); - if(room_avatar_thumbnail_data->loading_state == LoadingState::FINISHED_LOADING) { + 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)) fprintf(stderr, "Warning: failed to load texture for room avatar\n"); room_avatar_thumbnail_data->image.reset(); @@ -3961,6 +3964,9 @@ namespace QuickMedia { } } + if(sync_future_room_id.empty() && !result.rooms_body_items.empty()) + sync_future_room_id = result.rooms_body_items[0]->url; + if(matrix->get_new_room_messages(sync_future_room_id, result.body_items) != PluginResult::OK) { fprintf(stderr, "Failed to get new matrix messages in room: %s\n", sync_future_room_id.c_str()); } @@ -3975,7 +3981,7 @@ namespace QuickMedia { if(sync_future.valid() && sync_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { SyncFutureResult sync_result = sync_future.get(); // Ignore finished sync if it happened in another room. When we navigate back to the room we will get the messages again - if(sync_future_room_id == current_room_id) { + if(sync_future_room_id == current_room_id || !synced) { int num_items = tabs[MESSAGES_TAB_INDEX].body->items.size(); bool scroll_to_end = (num_items == 0 || (num_items > 0 && tabs[MESSAGES_TAB_INDEX].body->get_selected_item() == num_items - 1)); tabs[MESSAGES_TAB_INDEX].body->append_items(std::move(sync_result.body_items)); @@ -4008,6 +4014,12 @@ namespace QuickMedia { synced = true; } + if(set_read_marker_future.valid() && set_read_marker_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { + set_read_marker_future.get(); + read_marker_timer.restart(); + setting_read_marker = false; + } + if(fetching_previous_messages_running && previous_messages_future.valid() && previous_messages_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { BodyItems new_body_items = previous_messages_future.get(); fprintf(stderr, "Finished fetching older messages, num new messages: %zu\n", new_body_items.size()); @@ -4140,14 +4152,17 @@ namespace QuickMedia { if(tabs[selected_tab].type == ChatTabType::MESSAGES) { BodyItem *last_visible_item = tabs[selected_tab].body->get_last_fully_visible_item(); - if(chat_state != ChatState::URL_SELECTION && current_room_body_data && last_visible_item && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) { + if(chat_state != ChatState::URL_SELECTION && current_room_body_data && last_visible_item && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) { Message *message = (Message*)last_visible_item->userdata; if(message->timestamp > current_room_body_data->last_read_message_timestamp) { current_room_body_data->last_read_message_timestamp = message->timestamp; - read_marker_timer.restart(); - if(matrix->set_read_marker(current_room_id, message) != PluginResult::OK) { - fprintf(stderr, "Warning: failed to set read marker to %s\n", message->event_id.c_str()); - } + // TODO: What if the message is no longer valid? + setting_read_marker = true; + set_read_marker_future = std::async(std::launch::async, [matrix, current_room_id, message]() mutable { + if(matrix->set_read_marker(current_room_id, message) != PluginResult::OK) { + fprintf(stderr, "Warning: failed to set read marker to %s\n", message->event_id.c_str()); + } + }); } } -- cgit v1.2.3