From ff85dfb6a9b58d6e5a25c614e7aa3e061c6a3e1f Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 20 Aug 2021 00:54:13 +0200 Subject: List all notifications in notifications page (including the ones we get after starting up qm). This was caused by notifications body being overwritten with cache when navigating to it --- TODO | 3 ++- plugins/Matrix.hpp | 3 ++- src/QuickMedia.cpp | 13 +++++++++++ src/plugins/Matrix.cpp | 62 +++++++++++++++++++++++++++++--------------------- 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/TODO b/TODO index 1b5592c..f1d8ace 100644 --- a/TODO +++ b/TODO @@ -201,4 +201,5 @@ Support  ?. Add option to navigate studios/producers/author in AniList/MAL. Renable throttle detection after fixing it (it doesn't detect throttling well and it breaks for very long videos, such as 8 hour long videos). Show who deleted a message in matrix. -Sync should replace all messages in the room (except for the selected room?) to reduce ram usage when in many rooms and when quickmedia has been running for a long time doing sync. \ No newline at end of file +Sync should replace all messages in the room (except for the selected room?) to reduce ram usage when in many rooms and when quickmedia has been running for a long time doing sync. +Fix notifications not being marked as read correctly (they remain red!). \ No newline at end of file diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index 0d29821..1566212 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -495,7 +495,7 @@ namespace QuickMedia { Matrix *matrix; Body *notifications_body; MatrixRoomsPage *all_rooms_page; - std::unordered_map>> room_notifications; + std::unordered_map>> room_notifications; }; class MatrixInviteUserPage : public Page { @@ -651,6 +651,7 @@ namespace QuickMedia { std::mutex invite_mutex; std::vector notifications; + std::unordered_set notifications_by_event_id; std::mutex notifications_mutex; std::thread sync_thread; diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 8fd6b0b..a00f056 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -1674,6 +1674,8 @@ namespace QuickMedia { if(matrix->did_initial_sync_fail(err_msg)) { show_notification("QuickMedia", "Initial matrix sync failed, error: " + err_msg, Urgency::CRITICAL); matrix->logout(); + delete matrix; + matrix = new Matrix(); current_page = PageType::CHAT_LOGIN; chat_login_page(); after_matrix_login_page(); @@ -6356,6 +6358,8 @@ namespace QuickMedia { new_page = PageType::CHAT; matrix->stop_sync(); matrix->logout(); + delete matrix; + matrix = new Matrix(); // TODO: Instead of doing this, exit this current function and navigate to chat login page instead. //delete current_plugin; //current_plugin = new Matrix(); @@ -6767,6 +6771,8 @@ namespace QuickMedia { all_messages.clear(); show_notification("QuickMedia", "Initial matrix sync failed, error: " + err_msg, Urgency::CRITICAL); matrix->logout(); + delete matrix; + matrix = new Matrix(); current_page = PageType::CHAT_LOGIN; chat_login_page(); after_matrix_login_page(); @@ -6801,6 +6807,8 @@ namespace QuickMedia { all_messages.clear(); show_notification("QuickMedia", "Initial matrix sync failed, error: " + err_msg, Urgency::CRITICAL); matrix->logout(); + delete matrix; + matrix = new Matrix(); current_page = PageType::CHAT_LOGIN; chat_login_page(); after_matrix_login_page(); @@ -6824,6 +6832,11 @@ namespace QuickMedia { add_new_messages_to_current_room(all_messages_new); modify_related_messages_in_current_room(all_messages_new); unresolved_reactions.clear(); + after_token.clear(); + before_token.clear(), + fetched_enough_messages_top = false; + fetched_enough_messages_bottom = false; + fetch_messages_future.cancel(); process_reactions(all_messages_new); if(current_room->initial_prev_messages_fetch) { current_room->initial_prev_messages_fetch = false; diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index df4fa52..21375e7 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -406,7 +406,7 @@ namespace QuickMedia { bool is_window_focused = program->is_window_focused(); RoomData *current_room = program->get_current_chat_room(); - if(!sync_is_cache && message_dir == MessageDirection::AFTER && !is_initial_sync) { + if(!sync_is_cache && message_dir == MessageDirection::AFTER) { for(auto &message : messages) { if(message->notification_mentions_me) { std::string body = remove_reply_formatting(message->body); @@ -1026,7 +1026,7 @@ namespace QuickMedia { bool read; }; - static std::shared_ptr notification_to_body_item(Body *body, const MatrixNotification ¬ification) { + static std::shared_ptr notification_to_body_item(const MatrixNotification ¬ification) { auto body_item = BodyItem::create(""); body_item->set_author(notification.room->get_name()); body_item->set_description(notification.sender_user_id + ":\n" + notification.body); @@ -1065,16 +1065,16 @@ 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(notifications_body, notification); - room_notifications[notification.room].push_back(body_item); + auto body_item = notification_to_body_item(notification); + room_notifications[notification.room->id].push_back(body_item); result_items.push_back(body_item); }); } PluginResult MatrixNotificationsPage::lazy_fetch(BodyItems &result_items) { matrix->get_cached_notifications([this, &result_items](const MatrixNotification ¬ification) { - auto body_item = notification_to_body_item(notifications_body, notification); - room_notifications[notification.room].push_back(body_item); + auto body_item = notification_to_body_item(notification); + room_notifications[notification.room->id].push_back(body_item); result_items.push_back(body_item); }); return PluginResult::OK; @@ -1085,25 +1085,20 @@ namespace QuickMedia { } void MatrixNotificationsPage::add_notification(MatrixNotification notification) { - //int prev_selected_item = notifications_body->get_selected_item(); - //notifications_body->items.push_back(notification_to_body_item(notifications_body, notification)); - //notifications_body->set_selected_item(prev_selected_item - 1); - auto body_item = notification_to_body_item(notifications_body, notification); - room_notifications[notification.room].push_back(body_item); - notifications_body->prepend_item(body_item); - if(notifications_body->get_selected_item() > 0) - notifications_body->select_next_item(); + 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); } // TODO: Only loop unread items void MatrixNotificationsPage::set_room_as_read(RoomData *room) { - auto it = room_notifications.find(room); + auto it = room_notifications.find(room->id); if(it == room_notifications.end()) return; for(const auto &room_notification : it->second) { NotificationsExtraData *extra_data = static_cast(room_notification->extra.get()); - if(!extra_data->read && extra_data->room == room) { + 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); @@ -1622,15 +1617,18 @@ namespace QuickMedia { continue; } - MatrixNotification notification; - notification.room = room; - notification.event_id.assign(event_id_json.GetString(), event_id_json.GetStringLength()); - notification.sender_user_id.assign(sender_json.GetString(), sender_json.GetStringLength()); - notification.body = remove_reply_formatting(body_json.GetString()); - notification.timestamp = timestamp; - notification.read = read_json.GetBool(); - callback_func(notification); - notifications.push_back(std::move(notification)); + std::string event_id(event_id_json.GetString(), event_id_json.GetStringLength()); + if(notifications_by_event_id.insert(event_id).second) { + MatrixNotification notification; + notification.room = room; + notification.event_id = std::move(event_id); + notification.sender_user_id.assign(sender_json.GetString(), sender_json.GetStringLength()); + notification.body = remove_reply_formatting(body_json.GetString()); + notification.timestamp = timestamp; + notification.read = read_json.GetBool(); + callback_func(notification); + notifications.push_back(std::move(notification)); + } } return PluginResult::OK; } @@ -2078,11 +2076,23 @@ namespace QuickMedia { if(read_marker_message_timestamp == 0 || read_marker_message_timestamp < qm_read_marker) read_marker_message_timestamp = qm_read_marker; + std::lock_guard lock(notifications_mutex); 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