From 87fb6e5c0cce6e6aba8f646329af6f8070d27c63 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 21 Oct 2020 08:08:56 +0200 Subject: Matrix: fix room sorting for unread messages/mentions --- src/QuickMedia.cpp | 57 +++++++++++++----------------------------------------- 1 file changed, 13 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 4a81219..f944e7d 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -2967,28 +2967,8 @@ namespace QuickMedia { RoomData *current_room = nullptr; bool is_window_focused = window.hasFocus(); - // Returns -1 if no rooms or no unread rooms - auto find_top_body_position_for_unread_room = [&tabs](BodyItem *item_to_swap, int start_index) { - for(int i = start_index; i < (int)tabs[ROOMS_TAB_INDEX].body->items.size(); ++i) { - const auto &body_item = tabs[ROOMS_TAB_INDEX].body->items[i]; - if(static_cast(body_item->userdata)->last_message_read || body_item.get() == item_to_swap) - return i; - } - return -1; - }; - - // Returns -1 if no rooms or all rooms have unread mentions - auto find_top_body_position_for_mentioned_room = [&tabs](BodyItem *item_to_swap, int start_index) { - for(int i = start_index; i < (int)tabs[ROOMS_TAB_INDEX].body->items.size(); ++i) { - const auto &body_item = tabs[ROOMS_TAB_INDEX].body->items[i]; - if(!static_cast(body_item->userdata)->has_unread_mention || body_item.get() == item_to_swap) - return i; - } - return -1; - }; - auto process_new_room_messages = - [this, &selected_tab, ¤t_room, &is_window_focused, &tabs, &find_top_body_position_for_unread_room, &find_top_body_position_for_mentioned_room] + [this, &selected_tab, ¤t_room, &is_window_focused, &tabs] (RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable { for(auto &[room, messages] : room_sync_messages) { @@ -3002,6 +2982,7 @@ namespace QuickMedia { } } + bool has_unread_messages = false; for(auto &[room, messages] : room_sync_messages) { if(messages.empty()) continue; @@ -3029,35 +3010,13 @@ namespace QuickMedia { assert(room_body_item); if(last_unread_message) { + has_unread_messages = true; 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)); room_body_item->set_title_color(sf::Color(255, 100, 100)); room->last_message_read = false; - - // Swap order of rooms in body list to put rooms with mentions at the top and then unread messages and then all the other rooms - // TODO: Optimize with hash map instead of linear search? or cache the index - int room_body_index = tabs[ROOMS_TAB_INDEX].body->get_index_by_body_item(room_body_item); - if(room_body_index != -1) { - int body_swap_index = 0; - while(true) { - BodyItem *body_item = tabs[ROOMS_TAB_INDEX].body->items[room_body_index].get(); - RoomData *room = static_cast(body_item->userdata); - if(room->has_unread_mention) - body_swap_index = find_top_body_position_for_mentioned_room(body_item, body_swap_index); - else if(!room->last_message_read) - body_swap_index = find_top_body_position_for_unread_room(body_item, body_swap_index); - else - break; - - if(body_swap_index == -1) - break; - - std::swap(tabs[ROOMS_TAB_INDEX].body->items[room_body_index], tabs[ROOMS_TAB_INDEX].body->items[body_swap_index]); - ++body_swap_index; - } - } } else if(is_first_sync) { Message *last_unread_message = nullptr; for(auto it = messages.rbegin(), end = messages.rend(); it != end; ++it) { @@ -3070,6 +3029,16 @@ namespace QuickMedia { room_body_item->set_description(matrix->message_get_author_displayname(last_unread_message) + ": " + extract_first_line(last_unread_message->body, 150)); } } + + if(has_unread_messages) { + std::sort(tabs[ROOMS_TAB_INDEX].body->items.begin(), tabs[ROOMS_TAB_INDEX].body->items.end(), [](std::shared_ptr &item1, std::shared_ptr &item2) { + RoomData *item1_room = static_cast(item1->userdata); + RoomData *item2_room = static_cast(item2->userdata); + int item1_presence_sum = (int)!item1_room->last_message_read + (int)item1_room->has_unread_mention; + int item2_presence_sum = (int)!item2_room->last_message_read + (int)item2_room->has_unread_mention; + return item1_presence_sum > item2_presence_sum; + }); + } }; enum class ChatState { -- cgit v1.2.3