From 9a8e2e5c383713f471d5a0f977fbef07a5fc4738 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 21 Oct 2020 06:39:32 +0200 Subject: Matrix: dont count edit/redacts as new unread messages in a room, update local read marker --- src/QuickMedia.cpp | 41 +++++++++++++++++++++++++++++++---------- src/Text.cpp | 6 +++--- src/plugins/Matrix.cpp | 14 ++++++++++---- 3 files changed, 44 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 0021f96..4a81219 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -3006,17 +3006,30 @@ namespace QuickMedia { if(messages.empty()) continue; - BodyItem *room_body_item = static_cast(room->userdata); - assert(room_body_item); + std::shared_ptr me = matrix->get_me(room); + time_t read_marker_message_timestamp = 0; + if(me) { + auto read_marker_message = room->get_message_by_id(room->get_user_read_marker(me)); + if(read_marker_message) + read_marker_message_timestamp = read_marker_message->timestamp; + } // TODO: this wont always work because we dont display all types of messages from server, such as "joined", "left", "kicked", "banned", "changed avatar", "changed display name", etc. - bool unread_messages = false; - std::shared_ptr me = matrix->get_me(room); - if(room->has_unread_mention || (me && room->get_user_read_marker(me) != messages.back()->event_id)) - unread_messages = true; + // TODO: Binary search? + Message *last_unread_message = nullptr; + for(auto &message : messages) { + if(message->related_event_type != RelatedEventType::EDIT && message->related_event_type != RelatedEventType::REDACTION && message->timestamp > read_marker_message_timestamp) + last_unread_message = message.get(); + } + + if(!last_unread_message && !is_first_sync) + continue; - if(unread_messages) { - std::string room_desc = "Unread: " + matrix->message_get_author_displayname(messages.back().get()) + ": " + extract_first_line(messages.back()->body, 150); + BodyItem *room_body_item = static_cast(room->userdata); + assert(room_body_item); + + if(last_unread_message) { + std::string room_desc = "Unread: " + matrix->message_get_author_displayname(last_unread_message) + ": " + extract_first_line(last_unread_message->body, 150); if(room->has_unread_mention) room_desc += "\n** You were mentioned **"; // TODO: Better notification? room_body_item->set_description(std::move(room_desc)); @@ -3046,7 +3059,15 @@ namespace QuickMedia { } } } else if(is_first_sync) { - room_body_item->set_description(matrix->message_get_author_displayname(messages.back().get()) + ": " + extract_first_line(messages.back()->body, 150)); + Message *last_unread_message = nullptr; + for(auto it = messages.rbegin(), end = messages.rend(); it != end; ++it) { + if((*it)->related_event_type != RelatedEventType::EDIT && (*it)->related_event_type != RelatedEventType::REDACTION) { + last_unread_message = (*it).get(); + break; + } + } + if(last_unread_message) + room_body_item->set_description(matrix->message_get_author_displayname(last_unread_message) + ": " + extract_first_line(last_unread_message->body, 150)); } } }; @@ -3176,8 +3197,8 @@ namespace QuickMedia { Messages new_messages; if(matrix->get_all_synced_room_messages(current_room, new_messages) == PluginResult::OK) { tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(new_messages, matrix->get_me(current_room).get())); - tabs[MESSAGES_TAB_INDEX].body->select_last_item(); modify_related_messages_in_current_room(new_messages); + tabs[MESSAGES_TAB_INDEX].body->select_last_item(); } else { std::string err_msg = "Failed to get messages in room: " + current_room->id; show_notification("QuickMedia", err_msg, Urgency::CRITICAL); diff --git a/src/Text.cpp b/src/Text.cpp index a00d068..44730c3 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -282,14 +282,15 @@ namespace QuickMedia if(!update_even_if_not_dirty && !dirty) return; + dirty = false; vertices_linear.clear(); vertices[0].clear(); vertices[1].clear(); + boundingBox = sf::FloatRect(); + float hspace = font->getGlyph(' ', characterSize, false).advance + characterSpacing; float vspace = font->getLineSpacing(characterSize); // TODO: What about japanese font??? - boundingBox = sf::FloatRect(); - sf::Vector2f glyphPos; sf::Uint32 prevCodePoint = 0; for(usize textElementIndex = 0; textElementIndex < textElements.size(); ++textElementIndex) @@ -464,7 +465,6 @@ namespace QuickMedia boundingBox.width = std::max(boundingBox.width, get_text_quad_right_side(vertex_ref)); } boundingBox.height = num_lines * line_height; - dirty = false; // TODO: Clear vertices_linear when not in edit mode, but take into consideration switching between edit/not-edit mode } diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 7de8af9..b6f6f76 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -481,14 +481,17 @@ namespace QuickMedia { room_data->append_messages(new_messages); } - std::shared_ptr read_marker_message; - if(me) - read_marker_message = room_data->get_message_by_id(room_data->get_user_read_marker(me)); + time_t read_marker_message_timestamp = 0; + if(me) { + auto read_marker_message = room_data->get_message_by_id(room_data->get_user_read_marker(me)); + if(read_marker_message) + read_marker_message_timestamp = read_marker_message->timestamp; + } for(auto &message : new_messages) { // TODO: Is @room ok? shouldn't we also check if the user has permission to do @room? (only when notifications are limited to @mentions) // TODO: Is comparing against read marker timestamp ok enough? - if(has_unread_notifications && me && (!read_marker_message || read_marker_message->timestamp < message->timestamp)) + if(has_unread_notifications && me && message->timestamp > read_marker_message_timestamp) message->mentions_me = message_contains_user_mention(message->body, me->display_name) || message_contains_user_mention(message->body, me->user_id) || message_contains_user_mention(message->body, "@room"); } } @@ -1609,6 +1612,9 @@ namespace QuickMedia { if(download_to_string(homeserver + "/_matrix/client/r0/rooms/" + room->id + "/read_markers", server_response, std::move(additional_args), use_tor, true) != DownloadResult::OK) return PluginResult::NET_ERR; + auto me = get_me(room); + if(me) + room->set_user_read_marker(me, message->event_id); return PluginResult::OK; } -- cgit v1.2.3