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 --- TODO | 1 - src/QuickMedia.cpp | 41 +++++++++++++++++++++++++++++++---------- src/Text.cpp | 6 +++--- src/plugins/Matrix.cpp | 14 ++++++++++---- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/TODO b/TODO index fc65f22..6d75453 100644 --- a/TODO +++ b/TODO @@ -94,7 +94,6 @@ Readd autocomplete, but make it better with a proper list. Also readd 4chan logi Fix logout/login in matrix. Currently it doesn't work because data is cleared while sync is in progress, leading to the first sync sometimes being with previous data... Modify sfml to use GL_COMPRESSED_LUMINANCE and other texture compression modes (in sf::Texture). This reduces memory usage by half. Decrease memory usage even further (mostly in matrix /sync when part of large rooms) by using rapidjson SAX style API to stream json string into SAX style parsing. -Dont show red marker when receiving edit/redaction events in matrix. Sometimes we fail to get images in mangadex, most common reason being that the manga is licensed and we can't view the manga on mangadex. QuickMedia should implement mangaplus and redirect us to mangaplus plugin to view the manga, or simply show that we cant view the manga because its licensed. Show redacted messages even when part of the initial sync in matrix. Right now they are hidden while new sync redacted messages are not. Update displayname/avatar in matrix when updated in /sync. 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