aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Matrix.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-11-15 19:36:10 +0100
committerdec05eba <dec05eba@protonmail.com>2022-11-15 19:36:10 +0100
commit59c4a651ab9d795c0d1788a8ddf29949a56b1ab9 (patch)
tree63e025ebb51a7f9f844a1fa88ee1348cee0a43a9 /src/plugins/Matrix.cpp
parent7b25a28366be259dc9a165ba13e0be0512e19d78 (diff)
Matrix: use a local cache of latest read marker timestamps to try and avoid many unread message notices
Diffstat (limited to 'src/plugins/Matrix.cpp')
-rw-r--r--src/plugins/Matrix.cpp81
1 files changed, 67 insertions, 14 deletions
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index ba4111d..d3c6f81 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -730,7 +730,7 @@ namespace QuickMedia {
if(!room->body_item)
return;
- if(!sync_is_cache && (last_unread_message || room->unread_notification_count > 0)) {
+ if(!sync_is_cache && last_unread_message) {
bool is_window_focused = program->is_window_focused();
RoomData *current_room = program->get_current_chat_room();
Body *chat_body = chat_page ? chat_page->chat_body : nullptr;
@@ -748,20 +748,13 @@ namespace QuickMedia {
room->body_item->set_description_color(get_theme().faded_text_color);
}
- if(last_unread_message) {
- if(!room_desc.empty())
- room_desc += '\n';
- }
+ if(!room_desc.empty())
+ room_desc += '\n';
if(!unread_mentions && set_room_as_unread)
room_desc += "Unread: ";
- if(last_unread_message) {
- room->latest_message = extract_first_line_remove_newline_elipses(matrix->message_get_author_displayname(last_unread_message), AUTHOR_MAX_LENGTH) + ": " + message_to_room_description_text(matrix, last_unread_message, custom_emoji_max_size);
- } else {
- room->latest_message.clear();
- }
-
+ room->latest_message = extract_first_line_remove_newline_elipses(matrix->message_get_author_displayname(last_unread_message), AUTHOR_MAX_LENGTH) + ": " + message_to_room_description_text(matrix, last_unread_message, custom_emoji_max_size);
room_desc += room->latest_message;
room->body_item->set_description(std::move(room_desc));
@@ -1557,6 +1550,7 @@ namespace QuickMedia {
load_silenced_invites();
load_custom_emoji_from_cache();
+ load_qm_read_markers_from_cache();
sync_thread = std::thread([this, matrix_cache_dir]() {
sync_is_cache = true;
@@ -1764,6 +1758,8 @@ namespace QuickMedia {
filter_cached.reset();
finished_fetching_notifications = false;
custom_emoji_by_key.clear();
+ silenced_invites.clear();
+ qm_read_markers_by_room_cache.clear();
}
bool Matrix::is_initial_sync_finished() {
@@ -4815,6 +4811,9 @@ namespace QuickMedia {
Path custom_emoji_path = get_cache_dir().join("matrix").join("custom_emoji.json");
remove(custom_emoji_path.data.c_str());
+
+ Path read_markers_path = get_cache_dir().join("matrix").join("read_markers.json");
+ remove(read_markers_path.data.c_str());
//Path filter_cache_path = get_storage_dir().join("matrix").join("filter");
//remove(filter_cache_path.data.c_str());
for_files_in_dir(get_cache_dir().join("matrix").join("events"), [](const Path &filepath, FileType) {
@@ -5203,11 +5202,62 @@ namespace QuickMedia {
{ "--data-binary", buffer.GetString() }
};
- room->read_marker_event_timestamp = timestamp;
-
std::string server_response;
DownloadResult download_result = download_to_string(homeserver + "/_matrix/client/r0/user/" + my_user_id + "/rooms/" + room->id + "/account_data/qm.last_read_message_timestamp", server_response, std::move(additional_args), true);
- return download_result_to_plugin_result(download_result);
+ if(download_result != DownloadResult::OK)
+ return download_result_to_plugin_result(download_result);
+
+ room->read_marker_event_timestamp = timestamp;
+ update_room_qm_read_markers_in_cache(room->id, timestamp);
+ return PluginResult::OK;
+ }
+
+ // TODO: Separate file for each room?
+ void Matrix::load_qm_read_markers_from_cache() {
+ std::string file_content;
+ if(file_get_content(get_cache_dir().join("matrix").join("read_markers.json"), file_content) != 0)
+ return;
+
+ rapidjson::Document json_root;
+ rapidjson::ParseResult parse_result = json_root.Parse(file_content.c_str(), file_content.size());
+ if(parse_result.IsError()) {
+ fprintf(stderr, "Warning: failed to parse read_markers.json, error: %d\n", parse_result.Code());
+ return;
+ }
+
+ if(!json_root.IsObject()) {
+ fprintf(stderr, "Warning: failed to parse read_markers.json\n");
+ return;
+ }
+
+ qm_read_markers_by_room_cache.clear();
+ std::lock_guard<std::recursive_mutex> lock(room_data_mutex);
+ for(auto const &obj : json_root.GetObject()) {
+ if(!obj.name.IsString() || !obj.value.IsInt64())
+ continue;
+
+ std::string room_id = std::string(obj.name.GetString(), obj.name.GetStringLength());
+ auto room_it = room_data_by_id.find(room_id);
+ if(room_it != room_data_by_id.end())
+ rooms[room_it->second]->read_marker_event_timestamp = obj.value.GetInt64();
+ qm_read_markers_by_room_cache[std::move(room_id)] = obj.value.GetInt64();
+ }
+ }
+
+ void Matrix::update_room_qm_read_markers_in_cache(const std::string &room_id, int64_t timestamp) {
+ load_qm_read_markers_from_cache(); // TODO: Remove this?
+ qm_read_markers_by_room_cache[room_id] = timestamp;
+
+ rapidjson::Document request_data(rapidjson::kObjectType);
+ for(const auto &[key, val] : qm_read_markers_by_room_cache) {
+ request_data.AddMember(rapidjson::Value(key.c_str(), request_data.GetAllocator()).Move(), val, request_data.GetAllocator());
+ }
+
+ rapidjson::StringBuffer buffer;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+ request_data.Accept(writer);
+
+ file_overwrite_atomic(get_cache_dir().join("matrix").join("read_markers.json"), std::string(buffer.GetString(), buffer.GetSize()));
}
PluginResult Matrix::join_room(const std::string &room_id_or_name) {
@@ -5587,6 +5637,9 @@ namespace QuickMedia {
std::lock_guard<std::recursive_mutex> lock(room_data_mutex);
room->index = rooms.size();
room_data_by_id.insert(std::make_pair(room->id, room->index));
+ auto read_marker_it = qm_read_markers_by_room_cache.find(room->id);
+ if(read_marker_it != qm_read_markers_by_room_cache.end())
+ room->read_marker_event_timestamp = read_marker_it->second;
rooms.push_back(std::move(room));
}