From 16ca6e63f4fd1b407c826a5574dc20b3f9e71675 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 3 Nov 2020 01:07:57 +0100 Subject: Matrix: sync with filter, lazy member fetch (reducing sync time from 35 sec with huge server to 3 seconds) and cached fetch to 150ms). Properly show notifications for older messages. Reduce memory usage from 120mb to 13mb --- src/QuickMedia.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 14 deletions(-) (limited to 'src/QuickMedia.cpp') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index ad9cc7f..318aba8 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -1328,6 +1328,12 @@ namespace QuickMedia { load_sprite.setPosition(body_pos.x + body_size.x * 0.5f, body_pos.y + body_size.y * 0.5f); load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0); window.draw(load_sprite); + std::string err_msg; + if(matrix->did_initial_sync_fail(err_msg)) { + show_notification("QuickMedia", "Initial matrix sync failed, error: " + err_msg, Urgency::CRITICAL); + window.close(); + goto page_end; + } } window.display(); @@ -3050,7 +3056,7 @@ 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(message->mentions_me || (me && (message_contains_user_mention(message->body, me->display_name) || message_contains_user_mention(message->body, me->user_id)))) + if(me && (message_contains_user_mention(message->body, me->display_name) || message_contains_user_mention(message->body, me->user_id))) body_item->set_description_color(sf::Color(255, 100, 100)); return body_item; } @@ -3234,6 +3240,7 @@ namespace QuickMedia { Messages all_messages; matrix->get_all_synced_room_messages(current_room, all_messages); + size_t num_messages_in_room = all_messages.size(); tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(all_messages, matrix->get_me(current_room).get())); modify_related_messages_in_current_room(all_messages); tabs[MESSAGES_TAB_INDEX].body->select_last_item(); @@ -3337,7 +3344,6 @@ namespace QuickMedia { }; AsyncTask previous_messages_future; - RoomData *previous_messages_future_room = nullptr; //const int num_fetch_message_threads = 4; AsyncTask> fetch_message_future; @@ -3421,6 +3427,16 @@ namespace QuickMedia { sf::Vertex gradient_points[4]; double gradient_inc = 0; + bool initial_prev_messages_fetch = true; + if(num_messages_in_room < 10) { + previous_messages_future = [this, ¤t_room]() { + Messages messages; + if(matrix->get_previous_room_messages(current_room, messages) != PluginResult::OK) + fprintf(stderr, "Failed to get previous matrix messages in room: %s\n", current_room->id.c_str()); + return messages; + }; + } + sf::RectangleShape more_messages_below_rect; more_messages_below_rect.setFillColor(sf::Color(128, 50, 50)); @@ -3562,13 +3578,15 @@ namespace QuickMedia { previous_messages_future.cancel(); fetch_message_future.cancel(); typing_state_queue.close(); - program_kill_in_thread(typing_state_thread.get_id()); - if(typing_state_thread.joinable()) + if(typing_state_thread.joinable()) { + program_kill_in_thread(typing_state_thread.get_id()); typing_state_thread.join(); + } post_task_queue.close(); - program_kill_in_thread(post_thread.get_id()); - if(post_thread.joinable()) + if(post_thread.joinable()) { + program_kill_in_thread(post_thread.get_id()); post_thread.join(); + } unreferenced_event_by_room.clear(); @@ -3616,11 +3634,10 @@ namespace QuickMedia { } if(hit_top && !previous_messages_future.valid() && selected_tab == MESSAGES_TAB_INDEX && current_room) { gradient_inc = 0; - previous_messages_future_room = current_room; - previous_messages_future = [this, &previous_messages_future_room]() { + previous_messages_future = [this, ¤t_room]() { Messages messages; - if(matrix->get_previous_room_messages(previous_messages_future_room, messages) != PluginResult::OK) - fprintf(stderr, "Failed to get previous matrix messages in room: %s\n", previous_messages_future_room->id.c_str()); + if(matrix->get_previous_room_messages(current_room, messages) != PluginResult::OK) + fprintf(stderr, "Failed to get previous matrix messages in room: %s\n", current_room->id.c_str()); return messages; }; } @@ -3977,7 +3994,7 @@ namespace QuickMedia { fprintf(stderr, "Finished fetching older messages, num new messages: %zu\n", new_messages.size()); // Ignore finished fetch of messages if it happened in another room. When we navigate back to the room we will get the messages again size_t num_new_messages = new_messages.size(); - if(num_new_messages > 0 && previous_messages_future_room == current_room) { + 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()); size_t num_new_body_items = new_body_items.size(); @@ -3990,6 +4007,13 @@ namespace QuickMedia { modify_related_messages_in_current_room(new_messages); resolve_unreferenced_events_with_body_items(tabs[MESSAGES_TAB_INDEX].body->items.data(), num_new_body_items); } + if(initial_prev_messages_fetch) { + initial_prev_messages_fetch = false; + // XXX: Hack to scroll up while keeping the selected item (usually the last one) visible + int selected_item = tabs[MESSAGES_TAB_INDEX].body->get_selected_item(); + tabs[MESSAGES_TAB_INDEX].body->select_first_item(); + tabs[MESSAGES_TAB_INDEX].body->set_selected_item(selected_item, false); + } } if(fetch_message_future.ready()) { @@ -4118,14 +4142,19 @@ namespace QuickMedia { std::string room_desc = current_room_body_item->get_description(); if(strncmp(room_desc.c_str(), "Unread: ", 8) == 0) room_desc = room_desc.substr(8); - if(room_desc.size() >= 25 && strncmp(room_desc.c_str() + room_desc.size() - 25, "\n** You were mentioned **", 25) == 0) - room_desc = room_desc.substr(0, room_desc.size() - 25); + size_t last_line_start = room_desc.rfind('\n'); + if(last_line_start != std::string::npos && last_line_start != room_desc.size()) { + ++last_line_start; + size_t last_line_size = room_desc.size() - last_line_start; + if(last_line_size >= 23 && memcmp(&room_desc[last_line_start], "** ", 3) == 0 && memcmp(&room_desc[room_desc.size() - 20], "unread mention(s) **", 20) == 0) + room_desc.erase(room_desc.begin() + last_line_start - 1, room_desc.end()); + } current_room_body_item->set_description(std::move(room_desc)); // TODO: Show a line like nheko instead for unread messages, or something else current_room_body_item->set_title_color(sf::Color::White); current_room->last_message_read = true; // TODO: Maybe set this instead when the mention is visible on the screen? - current_room->has_unread_mention = false; + current_room->unread_notification_count = 0; } else { window.draw(more_messages_below_rect); } @@ -4159,6 +4188,12 @@ namespace QuickMedia { load_sprite.setPosition(body_pos.x + body_size.x * 0.5f, body_pos.y + body_size.y * 0.5f); load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0); window.draw(load_sprite); + std::string err_msg; + if(matrix->did_initial_sync_fail(err_msg)) { + show_notification("QuickMedia", "Initial matrix sync failed, error: " + err_msg, Urgency::CRITICAL); + window.close(); + goto chat_page_end; + } } window.display(); @@ -4167,8 +4202,14 @@ namespace QuickMedia { matrix_chat_page->should_clear_data = false; cleanup_tasks(); + std::string err_msg; while(!matrix->is_initial_sync_finished()) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); + if(matrix->did_initial_sync_fail(err_msg)) { + show_notification("QuickMedia", "Initial matrix sync failed, error: " + err_msg, Urgency::CRITICAL); + window.close(); + goto chat_page_end; + } } current_room = matrix->get_room_by_id(current_room->id); -- cgit v1.2.3