aboutsummaryrefslogtreecommitdiff
path: root/src/QuickMedia.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r--src/QuickMedia.cpp76
1 files changed, 56 insertions, 20 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 90abfcc..0021f96 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -2967,22 +2967,44 @@ namespace QuickMedia {
RoomData *current_room = nullptr;
bool is_window_focused = window.hasFocus();
- auto process_new_room_messages = [this, &selected_tab, &current_room, &is_window_focused](RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable {
- for(auto &[room, messages] : room_sync_messages) {
- if(messages.empty())
- continue;
+ // 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<RoomData*>(body_item->userdata)->last_message_read || body_item.get() == item_to_swap)
+ return i;
+ }
+ return -1;
+ };
- bool was_mentioned = false;
+ // 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<RoomData*>(body_item->userdata)->has_unread_mention || body_item.get() == item_to_swap)
+ return i;
+ }
+ return -1;
+ };
+
+ auto process_new_room_messages =
+ [this, &selected_tab, &current_room, &is_window_focused, &tabs, &find_top_body_position_for_unread_room, &find_top_body_position_for_mentioned_room]
+ (RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable
+ {
+ for(auto &[room, messages] : room_sync_messages) {
for(auto &message : messages) {
if(message->mentions_me) {
- was_mentioned = true;
room->has_unread_mention = true;
- //message->mentions_me = false;
// 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 || is_first_sync || selected_tab == ROOMS_TAB_INDEX)
show_notification("QuickMedia matrix - " + matrix->message_get_author_displayname(message.get()) + " (" + room->name + ")", message->body);
}
}
+ }
+
+ for(auto &[room, messages] : room_sync_messages) {
+ if(messages.empty())
+ continue;
BodyItem *room_body_item = static_cast<BodyItem*>(room->userdata);
assert(room_body_item);
@@ -2990,27 +3012,41 @@ namespace QuickMedia {
// 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<UserInfo> me = matrix->get_me(room);
- if(me && room->get_user_read_marker(me) != messages.back()->event_id)
+ if(room->has_unread_mention || (me && room->get_user_read_marker(me) != messages.back()->event_id))
unread_messages = true;
if(unread_messages) {
std::string room_desc = "Unread: " + matrix->message_get_author_displayname(messages.back().get()) + ": " + extract_first_line(messages.back()->body, 150);
- if(was_mentioned)
+ 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 room with the top one
+ // 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) {
- // std::swap(tabs[ROOMS_TAB_INDEX].body->items[room_body_index], tabs[ROOMS_TAB_INDEX].body->items[room_swap_index]);
- // ++room_swap_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<RoomData*>(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) {
room_body_item->set_description(matrix->message_get_author_displayname(messages.back().get()) + ": " + extract_first_line(messages.back()->body, 150));
- room->has_unread_mention = false;
}
}
};
@@ -3184,8 +3220,6 @@ namespace QuickMedia {
}
}
- tabs[selected_tab].body->select_last_item();
-
if(chat_state == ChatState::TYPING_MESSAGE) {
// TODO: Make asynchronous
if(matrix->post_message(current_room, text, std::nullopt, std::nullopt) == PluginResult::OK) {
@@ -3346,9 +3380,11 @@ namespace QuickMedia {
}
};
- auto add_new_messages_to_current_room = [this, &tabs, &current_room](Messages &messages) {
+ auto add_new_messages_to_current_room = [this, &tabs, &selected_tab, &current_room, &is_window_focused](Messages &messages) {
int num_items = tabs[MESSAGES_TAB_INDEX].body->items.size();
- bool scroll_to_end = (num_items == 0 || tabs[MESSAGES_TAB_INDEX].body->is_selected_item_last_visible_item());
+ bool scroll_to_end = num_items == 0;
+ if(tabs[MESSAGES_TAB_INDEX].body->is_selected_item_last_visible_item() && selected_tab == MESSAGES_TAB_INDEX && is_window_focused)
+ scroll_to_end = true;
BodyItem *selected_item = tabs[MESSAGES_TAB_INDEX].body->get_selected();
tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(messages, matrix->get_me(current_room).get()));