From 26614c66d4b57d857457fff8278fd8c1cb04d690 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 21 Apr 2021 02:48:43 +0200 Subject: Rework read marker, do not set it if not needed --- include/Body.hpp | 2 ++ src/Body.cpp | 9 +++++++++ src/QuickMedia.cpp | 51 ++++++++++++++++++++++++--------------------------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/include/Body.hpp b/include/Body.hpp index 90e75c8..98baa6d 100644 --- a/include/Body.hpp +++ b/include/Body.hpp @@ -214,6 +214,7 @@ namespace QuickMedia { // Returns null if no visible items. This is the item we can see the end of BodyItem* get_last_fully_visible_item(); + BodyItem* get_last_visible_item(); void clamp_selection(); @@ -286,6 +287,7 @@ namespace QuickMedia { bool last_item_fully_visible; int first_fully_visible_item; int last_fully_visible_item; + int last_visible_item = -1; sf::Clock draw_timer; sf::Clock frame_timer; double elapsed_time_sec = 0.0; diff --git a/src/Body.cpp b/src/Body.cpp index dae0ca2..534f2b5 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -368,6 +368,12 @@ namespace QuickMedia { return items[last_fully_visible_item].get(); } + BodyItem* Body::get_last_visible_item() { + if(last_visible_item < 0 || last_visible_item >= (int)items.size() || !items[last_visible_item]->visible) + return nullptr; + return items[last_visible_item].get(); + } + void Body::clamp_selection() { int num_items = (int)items.size(); if(items.empty()) @@ -524,6 +530,7 @@ namespace QuickMedia { offset_to_top = 0.0f; offset_to_bottom = 0.0f; mouse_left_clicked = false; + last_visible_item = -1; return; } @@ -672,6 +679,7 @@ namespace QuickMedia { draw_item(window, item.get(), prev_pos, size, item_height, i, content_progress, true, merge_with_previous); glDisable(GL_SCISSOR_TEST); ++num_visible_items; + last_visible_item = i; if(first_item_fully_visible) first_fully_visible_item = i; @@ -727,6 +735,7 @@ namespace QuickMedia { after_pos.y += item_height; after_pos.y += spacing_y; ++num_visible_items; + last_visible_item = i; BodyItem *next_body_item = get_next_visible_item(i); const bool merge_with_next = next_body_item && body_item_merge_handler && body_item_merge_handler(item.get(), next_body_item); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index a954353..e213f94 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -4222,35 +4222,12 @@ namespace QuickMedia { }); }; - bool remove_unread_marker = false; // TODO: How about instead fetching all messages we have, not only the visible ones? also fetch with multiple threads. - tabs[MESSAGES_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &me, &remove_unread_marker, &fetch_message_future, &tabs, &is_window_focused, &chat_state, &setting_read_marker, &read_marker_timer, &read_marker_timeout_ms, &set_read_marker_future, &fetch_body_item, &fetch_message_tab, MESSAGES_TAB_INDEX](BodyItem *body_item) { + tabs[MESSAGES_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &me, &fetch_message_future, &tabs, &fetch_body_item, &fetch_message_tab, MESSAGES_TAB_INDEX](BodyItem *body_item) { Message *message = static_cast(body_item->userdata); if(!message) return; - if(matrix->is_initial_sync_finished() && tabs[MESSAGES_TAB_INDEX].body->is_last_item_fully_visible() && message_is_timeline(message) && is_window_focused && chat_state != ChatState::URL_SELECTION && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) { - Message *read_message = message; - if(message->replaced_by) - read_message = message->replaced_by.get(); - // TODO: What if two messages have the same timestamp? - if(!read_message->event_id.empty() && read_message->timestamp > current_room->last_read_message_timestamp) { - remove_unread_marker = true; - //read_marker_timeout_ms = read_marker_timeout_ms_default; - current_room->last_read_message_timestamp = read_message->timestamp; - // TODO: What if the message is no longer valid? - setting_read_marker = true; - RoomData *room = current_room; - std::string event_id = read_message->event_id; - int64_t event_timestamp = read_message->timestamp; - set_read_marker_future = AsyncTask([this, room, event_id, event_timestamp]() mutable { - if(matrix->set_read_marker(room, event_id, event_timestamp) != PluginResult::OK) { - fprintf(stderr, "Warning: failed to set read marker to %s\n", event_id.c_str()); - } - }); - } - } - #if 0 if(message->user->resolve_state == UserResolveState::NOT_RESOLVED) { fetch_message = message; @@ -5185,8 +5162,10 @@ namespace QuickMedia { tabs[MESSAGES_TAB_INDEX].body->draw_item(window, currently_operating_on_item.get(), body_item_pos, body_item_size); } - if(selected_tab == MESSAGES_TAB_INDEX && current_room && current_room->body_item && !current_room->last_message_read) { - if(remove_unread_marker && tabs[selected_tab].body->is_last_item_fully_visible()) { + if(selected_tab == MESSAGES_TAB_INDEX && current_room && current_room->body_item && !current_room->last_message_read && matrix->is_initial_sync_finished()) { + BodyItem *last_visible_item = tabs[selected_tab].body->get_last_visible_item(); + Message *last_visible_item_message = static_cast(last_visible_item->userdata); + if(last_visible_item && last_visible_item_message && tabs[selected_tab].body->is_last_item_fully_visible() && message_is_timeline(last_visible_item_message) && is_window_focused && chat_state != ChatState::URL_SELECTION && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) { std::string room_desc = current_room->body_item->get_description(); if(strncmp(room_desc.c_str(), "Unread: ", 8) == 0) room_desc = room_desc.substr(8); @@ -5204,7 +5183,25 @@ namespace QuickMedia { current_room->last_message_read = true; // TODO: Maybe set this instead when the mention is visible on the screen? current_room->unread_notification_count = 0; - remove_unread_marker = false; + + Message *read_message = last_visible_item_message; + if(read_message->replaced_by) + read_message = read_message->replaced_by.get(); + // TODO: What if two messages have the same timestamp? + if(!read_message->event_id.empty() && read_message->timestamp > current_room->last_read_message_timestamp) { + //read_marker_timeout_ms = read_marker_timeout_ms_default; + current_room->last_read_message_timestamp = read_message->timestamp; + // TODO: What if the message is no longer valid? + setting_read_marker = true; + RoomData *room = current_room; + std::string event_id = read_message->event_id; + int64_t event_timestamp = read_message->timestamp; + set_read_marker_future = AsyncTask([this, room, event_id, event_timestamp]() mutable { + if(matrix->set_read_marker(room, event_id, event_timestamp) != PluginResult::OK) { + fprintf(stderr, "Warning: failed to set read marker to %s\n", event_id.c_str()); + } + }); + } } else if(!tabs[selected_tab].body->is_last_item_fully_visible()) { window.draw(more_messages_below_rect); } -- cgit v1.2.3