From dd4573e05cdfa2d9b99ef7a49c99e27c201da3e9 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 4 Sep 2021 00:30:06 +0200 Subject: Matrix: fix messages that dont mention us being added to notifications list. Also fix read status for notifications --- src/Body.cpp | 12 ++++++++ src/QuickMedia.cpp | 9 ++---- src/plugins/Matrix.cpp | 82 ++++++++++++++++++++++++++++++-------------------- 3 files changed, 65 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/Body.cpp b/src/Body.cpp index 1762ba5..afa1dae 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -315,6 +315,18 @@ namespace QuickMedia { items.insert(items.begin() + dst_index - 1, std::move(item_to_move)); } + size_t Body::insert_item_by_timestamp_reverse(std::shared_ptr body_item) { + apply_search_filter_for_item(body_item.get()); + for(size_t i = 0; i < items.size(); ++i) { + if(body_item->get_timestamp() > items[i]->get_timestamp()) { + items.insert(items.begin() + i, std::move(body_item)); + return i; + } + } + items.insert(items.begin(), std::move(body_item)); + return 0; + } + // TODO: Binary search and use hint to start search from start or end (for example when adding "previous" items or "next" items) size_t Body::insert_item_by_timestamp(std::shared_ptr body_item) { apply_search_filter_for_item(body_item.get()); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 1b48743..f66e23f 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -1817,7 +1817,7 @@ namespace QuickMedia { } } - bool Program::page_loop(std::vector &tabs, int start_tab_index, PageLoopSubmitHandler after_submit_handler) { + bool Program::page_loop(std::vector &tabs, int start_tab_index, PageLoopSubmitHandler after_submit_handler, bool go_to_previous_on_escape) { if(tabs.empty()) { show_notification("QuickMedia", "No tabs provided!", Urgency::CRITICAL); return false; @@ -2169,7 +2169,7 @@ namespace QuickMedia { if(event.type == sf::Event::Resized || event.type == sf::Event::GainedFocus) redraw = true; else if(event.type == sf::Event::KeyPressed) { - if(event.key.code == sf::Keyboard::Escape) { + if(event.key.code == sf::Keyboard::Escape && go_to_previous_on_escape) { return false; } else if(event.key.code == sf::Keyboard::Enter) { if(!tabs[selected_tab].search_bar) { @@ -7084,10 +7084,7 @@ namespace QuickMedia { tabs.push_back(Tab{std::move(invites_body), std::move(matrix_invites_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); tabs.push_back(Tab{std::move(room_directory_body), std::move(matrix_room_directory_page), create_search_bar("Server to search on...", SEARCH_DELAY_FILTER)}); - while(window.isOpen()) { - page_loop(tabs, 2); - } - + page_loop(tabs, 2, nullptr, false); matrix->stop_sync(); } diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 21375e7..e95b74b 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -413,7 +413,8 @@ namespace QuickMedia { bool read = true; // TODO: What if the message or username begins with "-"? also make the notification image be the avatar of the user if((!is_window_focused || room != current_room) && message->related_event_type != RelatedEventType::EDIT && message->related_event_type != RelatedEventType::REDACTION) { - show_notification("QuickMedia matrix - " + extract_first_line_remove_newline_elipses(matrix->message_get_author_displayname(message.get()), AUTHOR_MAX_LENGTH) + " (" + room->get_name() + ")", body); + if(notifications_shown.insert(message->event_id).second) + show_notification("QuickMedia matrix - " + extract_first_line_remove_newline_elipses(matrix->message_get_author_displayname(message.get()), AUTHOR_MAX_LENGTH) + " (" + room->get_name() + ")", body); read = false; } @@ -452,7 +453,8 @@ namespace QuickMedia { } void MatrixQuickMedia::add_unread_notification(MatrixNotification notification) { - show_notification("QuickMedia matrix - " + notification.sender_user_id + " (" + notification.room->get_name() + ")", notification.body); + if(notifications_shown.insert(notification.event_id).second) + show_notification("QuickMedia matrix - " + notification.sender_user_id + " (" + notification.room->get_name() + ")", notification.body); } void MatrixQuickMedia::add_user(MatrixEventUserInfo user_info) { @@ -858,8 +860,7 @@ namespace QuickMedia { } void MatrixInvitesPage::add_body_item(std::shared_ptr body_item) { - // TODO: Insert in reverse order (to show the latest invite at the top?) - body->insert_item_by_timestamp(std::move(body_item)); + body->insert_item_by_timestamp_reverse(std::move(body_item)); if(body->get_num_items() != prev_invite_count) { prev_invite_count = body->get_num_items(); title = "Invites (" + std::to_string(body->get_num_items()) + ")"; @@ -1066,17 +1067,34 @@ namespace QuickMedia { PluginResult MatrixNotificationsPage::get_page(const std::string&, int, BodyItems &result_items) { return matrix->get_previous_notifications([this, &result_items](const MatrixNotification ¬ification) { auto body_item = notification_to_body_item(notification); - room_notifications[notification.room->id].push_back(body_item); - result_items.push_back(body_item); + if(room_notifications[notification.room->id].insert(std::make_pair(notification.event_id, body_item)).second) + result_items.push_back(body_item); }); } PluginResult MatrixNotificationsPage::lazy_fetch(BodyItems &result_items) { - matrix->get_cached_notifications([this, &result_items](const MatrixNotification ¬ification) { + BodyItems new_body_items; + for(const auto &pending_room_notifications : pending_room_notifications) { + for(const auto ¬ification : pending_room_notifications.second) { + auto body_item = notification_to_body_item(notification.second); + if(room_notifications[notification.second.room->id].insert(std::make_pair(notification.second.event_id, body_item)).second) + new_body_items.push_back(std::move(body_item)); + } + } + pending_room_notifications.clear(); + + matrix->get_cached_notifications([this, &new_body_items](const MatrixNotification ¬ification) { auto body_item = notification_to_body_item(notification); - room_notifications[notification.room->id].push_back(body_item); - result_items.push_back(body_item); + if(room_notifications[notification.room->id].insert(std::make_pair(notification.event_id, body_item)).second) + new_body_items.push_back(body_item); + }); + + std::sort(new_body_items.begin(), new_body_items.end(), [](const std::shared_ptr &body_item1, const std::shared_ptr &body_item2) { + return body_item1->get_timestamp() > body_item2->get_timestamp(); }); + + result_items = std::move(new_body_items); + has_fetched = true; return PluginResult::OK; } @@ -1085,23 +1103,34 @@ namespace QuickMedia { } void MatrixNotificationsPage::add_notification(MatrixNotification notification) { + if(!has_fetched) { + pending_room_notifications[notification.room->id][notification.event_id] = std::move(notification); + return; + } + auto body_item = notification_to_body_item(notification); - room_notifications[notification.room->id].push_back(body_item); - notifications_body->insert_item_by_timestamp(body_item); + if(room_notifications[notification.room->id].insert(std::make_pair(notification.event_id, body_item)).second) + notifications_body->insert_item_by_timestamp_reverse(std::move(body_item)); } // TODO: Only loop unread items void MatrixNotificationsPage::set_room_as_read(RoomData *room) { - auto it = room_notifications.find(room->id); - if(it == room_notifications.end()) - return; + auto pending_it = pending_room_notifications.find(room->id); + if(pending_it != pending_room_notifications.end()) { + for(auto &room_notification : pending_it->second) { + room_notification.second.read = true; + } + } - for(const auto &room_notification : it->second) { - NotificationsExtraData *extra_data = static_cast(room_notification->extra.get()); - if(!extra_data->read) { - extra_data->read = true; - room_notification->set_author_color(get_current_theme().text_color); - room_notification->set_description_color(get_current_theme().text_color); + auto it = room_notifications.find(room->id); + if(it != room_notifications.end()) { + for(const auto &room_notification : it->second) { + NotificationsExtraData *extra_data = static_cast(room_notification.second->extra.get()); + if(!extra_data->read) { + extra_data->read = true; + room_notification.second->set_author_color(get_current_theme().text_color); + room_notification.second->set_description_color(get_current_theme().text_color); + } } } } @@ -2080,19 +2109,8 @@ namespace QuickMedia { 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(me && message->timestamp > read_marker_message_timestamp) { + if(me && message->timestamp > read_marker_message_timestamp) message->notification_mentions_me = message_contains_user_mention(message->body, my_display_name) || message_contains_user_mention(message->body, me->user_id) || message_contains_user_mention(message->body, "@room"); - if(notifications_by_event_id.insert(message->event_id).second) { - MatrixNotification notification; - notification.room = room_data; - notification.event_id = message->event_id; - notification.sender_user_id = message->user->user_id; - notification.body = remove_reply_formatting(message->body);; - notification.timestamp = message->timestamp; - notification.read = false; - notifications.insert(notifications.begin(), std::move(notification)); - } - } } } -- cgit v1.2.3