From 07c8a8f1d469672be5196570608cf0d14b4d5b21 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 9 Feb 2021 10:38:39 +0100 Subject: Matrix: test: only show m.room.message types in room list description, sort room list by activity, improve initial sync time --- plugins/Matrix.hpp | 1 + src/QuickMedia.cpp | 42 +++++++++++-------------- src/plugins/Matrix.cpp | 84 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 76 insertions(+), 51 deletions(-) diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index df8fa43..09500a6 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -147,6 +147,7 @@ namespace QuickMedia { bool pinned_events_updated = false; bool name_is_fallback = false; bool avatar_is_fallback = false; + std::atomic_int64_t last_message_timestamp = 0; std::atomic_int unread_notification_count = 0; diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 551da5e..552ceae 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -3740,11 +3740,28 @@ 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_message, &find_body_item_by_event_id, &fetch_body_item, &fetch_message_tab](BodyItem *body_item) { + tabs[MESSAGES_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &me, &fetch_message_future, &tabs, &is_window_focused, &chat_state, &setting_read_marker, &read_marker_timer, &read_marker_timeout_ms, &set_read_marker_future, &find_body_item_by_event_id, &fetch_body_item, &fetch_message_tab](BodyItem *body_item) { Message *message = static_cast(body_item->userdata); if(!message) return; + if(message->type >= MessageType::TEXT && message->type <= MessageType::FILE && is_window_focused && chat_state != ChatState::URL_SELECTION && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) { + // TODO: What if two messages have the same timestamp? + if(message && !message->event_id.empty() && message->timestamp > current_room->last_read_message_timestamp) { + //read_marker_timeout_ms = read_marker_timeout_ms_default; + current_room->last_read_message_timestamp = message->timestamp; + // TODO: What if the message is no longer valid? + setting_read_marker = true; + RoomData *room = current_room; + std::string event_id = message->event_id; + set_read_marker_future = [this, room, event_id]() mutable { + if(matrix->set_read_marker(room, event_id) != PluginResult::OK) { + fprintf(stderr, "Warning: failed to set read marker to %s\n", event_id.c_str()); + } + }; + } + } + #if 0 if(message->user->resolve_state == UserResolveState::NOT_RESOLVED) { fetch_message = message; @@ -4745,29 +4762,6 @@ namespace QuickMedia { } } - if(selected_tab == MESSAGES_TAB_INDEX && current_room && matrix->is_initial_sync_finished()) { - BodyItem *last_visible_item = tabs[selected_tab].body->get_last_fully_visible_item(); - if(last_visible_item && tabs[selected_tab].body->is_last_item_fully_visible() && !tabs[selected_tab].body->items.empty()) - last_visible_item = tabs[selected_tab].body->items.back().get(); - if(is_window_focused && chat_state != ChatState::URL_SELECTION && current_room && last_visible_item && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) { - Message *message = (Message*)last_visible_item->userdata; - // TODO: What if two messages have the same timestamp? - if(message && !message->event_id.empty() && message->timestamp > current_room->last_read_message_timestamp) { - //read_marker_timeout_ms = read_marker_timeout_ms_default; - current_room->last_read_message_timestamp = message->timestamp; - // TODO: What if the message is no longer valid? - setting_read_marker = true; - RoomData *room = current_room; - std::string event_id = message->event_id; - set_read_marker_future = [this, room, event_id]() mutable { - if(matrix->set_read_marker(room, event_id) != PluginResult::OK) { - fprintf(stderr, "Warning: failed to set read marker to %s\n", event_id.c_str()); - } - }; - } - } - } - if(selected_tab == MESSAGES_TAB_INDEX && current_room) { window.draw(chat_input_shade); chat_input.draw(window); //chat_input.draw(window, false); diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 9a785b6..6900dbc 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -23,7 +23,7 @@ static const char* SERVICE_NAME = "matrix"; static const char* OTHERS_ROOM_TAG = "tld.name.others"; // Filter without account data -static const char* INITIAL_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"limit\":1,\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"limit\":1,\"types\":[\"m.fully_read\",\"m.tag\"],\"lazy_load_members\":true}}}"; +static const char* INITIAL_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"types\":[\"m.room.message\"],\"limit\":1,\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"limit\":1,\"types\":[\"m.fully_read\",\"m.tag\"],\"lazy_load_members\":true}}}"; static const char* ADDITIONAL_MESSAGES_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"limit\":20,\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true}}}"; static const char* CONTINUE_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"types\":[\"m.fully_read\",\"m.tag\"],\"lazy_load_members\":true}}}"; @@ -157,27 +157,35 @@ namespace QuickMedia { size_t RoomData::prepend_messages_reverse(const std::vector> &new_messages) { std::lock_guard lock(room_mutex); + int64_t last_new_message_timestamp = last_message_timestamp; size_t num_new_messages = 0; for(auto it = new_messages.begin(); it != new_messages.end(); ++it) { if(message_by_event_id.find((*it)->event_id) == message_by_event_id.end()) { + if((*it)->type >= MessageType::TEXT && (*it)->type <= MessageType::FILE) + last_new_message_timestamp = std::max(last_new_message_timestamp, (*it)->timestamp); message_by_event_id.insert(std::make_pair((*it)->event_id, *it)); messages.insert(messages.begin(), std::move(*it)); ++num_new_messages; } } + last_message_timestamp = last_new_message_timestamp; return num_new_messages; } size_t RoomData::append_messages(const std::vector> &new_messages) { std::lock_guard lock(room_mutex); + int64_t last_new_message_timestamp = last_message_timestamp; size_t num_new_messages = 0; for(auto it = new_messages.begin(); it != new_messages.end(); ++it) { if(message_by_event_id.find((*it)->event_id) == message_by_event_id.end()) { + if((*it)->type >= MessageType::TEXT && (*it)->type <= MessageType::FILE) + last_new_message_timestamp = std::max(last_new_message_timestamp, (*it)->timestamp); message_by_event_id.insert(std::make_pair((*it)->event_id, *it)); messages.push_back(std::move(*it)); ++num_new_messages; } } + last_message_timestamp = last_new_message_timestamp; return num_new_messages; } @@ -398,6 +406,7 @@ namespace QuickMedia { } static void sort_room_body_items(std::vector> &room_body_items) { + #if 0 std::sort(room_body_items.begin(), room_body_items.end(), [](const std::shared_ptr &body_item1, const std::shared_ptr &body_item2) { return strcasecmp(body_item1->get_title().c_str(), body_item2->get_title().c_str()) < 0; }); @@ -414,6 +423,14 @@ namespace QuickMedia { return strcasecmp(body_item1->get_title().c_str(), body_item2->get_title().c_str()) < 0; }); #endif + #endif + std::sort(room_body_items.begin(), room_body_items.end(), [](const std::shared_ptr &body_item1, const std::shared_ptr &body_item2) { + RoomData *room1 = static_cast(body_item1->userdata); + RoomData *room2 = static_cast(body_item2->userdata); + int64_t room1_focus_sum = room1->last_message_timestamp; + int64_t room2_focus_sum = room2->last_message_timestamp; + return room1_focus_sum > room2_focus_sum; + }); } void MatrixQuickMedia::update(MatrixPageType page_type) { @@ -443,9 +460,22 @@ namespace QuickMedia { } static std::shared_ptr get_last_message_by_timestamp(const Messages &messages) { + #if 0 return *std::max_element(messages.begin(), messages.end(), [](const std::shared_ptr &message1, const std::shared_ptr &message2) { return message1->timestamp < message2->timestamp; }); + #else + if(messages.empty()) + return nullptr; + size_t last_message_index = 0; + for(size_t i = 1; i < messages.size(); ++i) { + if(messages[i]->type >= MessageType::TEXT && messages[i]->type <= MessageType::FILE && messages[i]->timestamp >= messages[last_message_index]->timestamp) + last_message_index = i; + } + if(messages[last_message_index]->type >= MessageType::TEXT && messages[last_message_index]->type <= MessageType::FILE) + return messages[last_message_index]; + return nullptr; + #endif } static std::string message_to_room_description_text(Message *message) { @@ -1019,32 +1049,6 @@ namespace QuickMedia { { "-m", "35" } }; - sync_additional_messages_thread = std::thread([this]() { - std::vector additional_args = { - { "-H", "Authorization: Bearer " + access_token }, - { "-m", "35" } - }; - - char url[1024]; - std::string filter_encoded = url_param_encode(ADDITIONAL_MESSAGES_FILTER); - snprintf(url, sizeof(url), "%s/_matrix/client/r0/sync?filter=%s&timeout=0", homeserver.c_str(), filter_encoded.c_str()); - - rapidjson::Document json_root; - std::string err_msg; - DownloadResult download_result = download_json(json_root, url, additional_args, use_tor, true, &err_msg); - if(download_result != DownloadResult::OK) { - fprintf(stderr, "/sync for additional messages failed\n"); - return; - } - - // TODO: Test? - //if(next_batch.empty()) - // clear_sync_cache_for_new_sync(); - - additional_messages_queue.pop_wait(); - parse_sync_response(json_root, true, false); - }); - const rapidjson::Value *next_batch_json; PluginResult result; bool initial_sync = true; @@ -1121,6 +1125,32 @@ namespace QuickMedia { const rapidjson::Value ¬ification_json = GetMember(json_root, "notifications"); parse_notifications(notification_json); + + { + std::vector additional_args = { + { "-H", "Authorization: Bearer " + access_token }, + { "-m", "35" } + }; + + char url[1024]; + std::string filter_encoded = url_param_encode(ADDITIONAL_MESSAGES_FILTER); + snprintf(url, sizeof(url), "%s/_matrix/client/r0/sync?filter=%s&timeout=0", homeserver.c_str(), filter_encoded.c_str()); + + rapidjson::Document json_root; + std::string err_msg; + DownloadResult download_result = download_json(json_root, url, additional_args, use_tor, true, &err_msg); + if(download_result != DownloadResult::OK) { + fprintf(stderr, "/sync for additional messages failed\n"); + return; + } + + // TODO: Test? + //if(next_batch.empty()) + // clear_sync_cache_for_new_sync(); + + additional_messages_queue.pop_wait(); + parse_sync_response(json_root, true, false); + } }); filter_encoded = url_param_encode(CONTINUE_FILTER); -- cgit v1.2.3