From 4aa395334456e04eb21e36c85295977feb4e89b0 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 6 May 2023 00:27:21 +0200 Subject: Matrix: try to fix missing messages (limited room messages) --- plugins/Matrix.hpp | 4 ++++ src/QuickMedia.cpp | 1 + src/plugins/Matrix.cpp | 46 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index 0eb8766..4a25f74 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -187,6 +187,7 @@ namespace QuickMedia { const Messages& get_messages_thread_unsafe() const; const std::vector& get_pinned_events_thread_unsafe() const; + void clear_messages(); bool has_prev_batch(); void set_prev_batch(const std::string &new_prev_batch); @@ -317,6 +318,7 @@ namespace QuickMedia { // Note: calling |room| methods inside this function is not allowed virtual void room_remove_tag(RoomData *room, const std::string &tag) = 0; virtual void room_add_new_messages(RoomData *room, const Messages &messages, bool is_initial_sync, MessageDirection message_dir) = 0; + virtual void room_clear_messages(RoomData *room) = 0; virtual void add_invite(const std::string &room_id, const Invite &invite) = 0; virtual void remove_invite(const std::string &room_id) = 0; @@ -349,6 +351,7 @@ namespace QuickMedia { void room_add_tag(RoomData *room, const std::string &tag) override; void room_remove_tag(RoomData *room, const std::string &tag) override; void room_add_new_messages(RoomData *room, const Messages &messages, bool is_initial_sync, MessageDirection message_dir) override; + void room_clear_messages(RoomData *room) override; void add_invite(const std::string &room_id, const Invite &invite) override; void remove_invite(const std::string &room_id) override; @@ -567,6 +570,7 @@ namespace QuickMedia { Body *chat_body = nullptr; bool messages_tab_visible = false; + bool is_regular_navigation = true; const std::string jump_to_event_id; private: diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 6c38a8d..5b7a4a6 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -6542,6 +6542,7 @@ namespace QuickMedia { sent_messages.clear(); fetched_messages_set.clear(); tabs[MESSAGES_TAB_INDEX].body->clear_items(); + matrix_chat_page->is_regular_navigation = false; matrix->clear_previous_messages_token(current_room); for(Messages *message_list : messages) { diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 41dea9f..c59a819 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -38,11 +38,8 @@ namespace QuickMedia { // Filter without account data. TODO: We include pinned events but limit events to 1. That means if the last event is a pin, // then we cant see room message preview. TODO: Fix this somehow. // TODO: What about state events in initial sync in timeline? such as user display name change. - // TODO: CONTINUE_FILTER has a hack right now ("limit:"999999) which also slows down sync. - // It should instead only get the latest message and then check if messages were limited ("there is a field in the response: limited: true") - // and find the gaps between prev_batch and previous sync. static const char* INITIAL_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"types\":[\"qm.emoji\",\"m.direct\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\",\"m.room.canonical_alias\",\"m.space.child\"],\"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\",\"qm.last_read_message_timestamp\"],\"lazy_load_members\":true}}}"; - static const char* CONTINUE_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"types\":[\"qm.emoji\",\"m.direct\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\",\"m.room.canonical_alias\",\"m.space.child\"],\"lazy_load_members\":true},\"timeline\":{\"lazy_load_members\":true,\"limit\":999999},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"types\":[\"m.fully_read\",\"m.tag\",\"qm.last_read_message_timestamp\"],\"lazy_load_members\":true}}}"; + static const char* CONTINUE_FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"types\":[\"qm.emoji\",\"m.direct\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\",\"m.room.canonical_alias\",\"m.space.child\"],\"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\",\"qm.last_read_message_timestamp\"],\"lazy_load_members\":true}}}"; static bool is_gpg_installed = false; static bool gpg_installed_checked = false; @@ -509,6 +506,13 @@ namespace QuickMedia { return messages; } + void RoomData::clear_messages() { + std::lock_guard lock(room_mutex); + messages.clear(); + message_by_event_id.clear(); + messages_read_index = 0; + } + const std::vector& RoomData::get_pinned_events_thread_unsafe() const { return pinned_events; } @@ -681,6 +685,13 @@ namespace QuickMedia { update_room_description(room, messages, is_initial_sync); } + void MatrixQuickMedia::room_clear_messages(RoomData *room) { + RoomData *current_room = program->get_current_chat_room(); + if(current_room == room && chat_page && chat_page->is_regular_navigation && chat_page->chat_body) { + chat_page->chat_body->clear_items(); + } + } + void MatrixQuickMedia::add_invite(const std::string &room_id, const Invite &invite) { std::string invited_by_display_name = extract_first_line_remove_newline_elipses(invite.invited_by->room->get_user_display_name(invite.invited_by), AUTHOR_MAX_LENGTH); auto body_item = BodyItem::create(invite.room_name); @@ -1559,7 +1570,9 @@ namespace QuickMedia { return PluginResult::OK; NotificationsExtraData *extra_data = static_cast(selected_item->extra.get()); - result_tabs.push_back(Tab{nullptr, std::make_unique(program, extra_data->room->id, all_rooms_page, selected_item->url), nullptr}); + auto chat_page = std::make_unique(program, extra_data->room->id, all_rooms_page, selected_item->url); + chat_page->is_regular_navigation = false; + result_tabs.push_back(Tab{nullptr, std::move(chat_page), nullptr}); return PluginResult::OK; } @@ -1704,8 +1717,10 @@ namespace QuickMedia { if(parse_result.IsError()) continue; // This should NEVER happen. Do initial sync if it does and remove cache? :( TODO - if(parse_sync_response(doc, false) != PluginResult::OK) + if(parse_sync_response(doc, false) != PluginResult::OK) { fprintf(stderr, "Failed to parse cached sync response\n"); + continue; + } next_batch_json = &GetMember(doc, "next_batch"); if(next_batch_json->IsString()) { @@ -2324,11 +2339,20 @@ namespace QuickMedia { has_unread_notifications = true; } - // TODO: timeline_json may contain "prev_batch", if so set it for the room. - // TODO: timeline_json may contain "limited" and if it's set to true then clear the messages in the room - // here so we only show the new messages. - // This will allow us to fetch older messages. But what if we do sync and we have limited messages - // but then receive a new sync and then restart quickmedia again and this time we dont have "limited" messages? + const rapidjson::Value &prev_batch_json = GetMember(timeline_json, "prev_batch"); + const rapidjson::Value &limited_json = GetMember(timeline_json, "limited"); + if(limited_json.IsBool() && limited_json.GetBool() == true) { + if(prev_batch_json.IsString()) + room->set_prev_batch(prev_batch_json.GetString()); + + room->clear_messages(); + ui_thread_tasks.push([this, room]{ + delegate->room_clear_messages(room); + }); + } + + if(prev_batch_json.IsString() && !room->has_prev_batch()) + room->set_prev_batch(prev_batch_json.GetString()); const rapidjson::Value &events_json = GetMember(timeline_json, "events"); events_add_user_info(events_json, room, 0); -- cgit v1.2.3