From 517119dfc65a185062b473499988ddea13959fcd Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 28 May 2021 16:32:04 +0200 Subject: Set correct read marker if the latest message is an edit --- src/QuickMedia.cpp | 92 +++++++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 7dbccae..c2dbf1c 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -4810,17 +4810,12 @@ namespace QuickMedia { }); }; - Message *last_visible_timeline_message = nullptr; - // 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, &last_visible_timeline_message, &fetch_message_future, &tabs, &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(message_is_timeline(message) && (!last_visible_timeline_message || message->timestamp > last_visible_timeline_message->timestamp)) - last_visible_timeline_message = message; - if(message->related_event_id.empty() || message->related_event_type != RelatedEventType::REPLY || (body_item->embedded_item_status != FetchStatus::NONE && body_item->embedded_item_status != FetchStatus::QUEUED_LOADING)) return; @@ -5811,44 +5806,55 @@ namespace QuickMedia { } if(selected_tab == MESSAGES_TAB_INDEX && current_room && current_room->body_item && !current_room->last_message_read && matrix->is_initial_sync_finished()) { - if(last_visible_timeline_message && !tabs[selected_tab].body->is_bottom_cut_off() && 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); - size_t last_line_start = room_desc.rfind('\n'); - if(last_line_start != std::string::npos && last_line_start != room_desc.size()) { - ++last_line_start; - size_t last_line_size = room_desc.size() - last_line_start; - if(last_line_size >= 23 && memcmp(&room_desc[last_line_start], "** ", 3) == 0 && memcmp(&room_desc[room_desc.size() - 20], "unread mention(s) **", 20) == 0) - room_desc.erase(room_desc.begin() + last_line_start - 1, room_desc.end()); + if(!tabs[selected_tab].body->is_bottom_cut_off() && is_window_focused && chat_state != ChatState::URL_SELECTION && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) { + auto &body_items = tabs[selected_tab].body->items; + int last_timeline_message = (int)body_items.size() - 1; + for(int i = last_timeline_message - 1; i >= 0; --i) { + BodyItem *item = body_items[i].get(); + Message *message = static_cast(item->userdata); + if(item->visible && message && message_is_timeline(message)) + break; } - current_room->body_item->set_description(std::move(room_desc)); - current_room->body_item->set_description_color(sf::Color(179, 179, 179)); - // TODO: Show a line like nheko instead for unread messages, or something else - current_room->body_item->set_title_color(sf::Color::White); - 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; - - matrix_chat_page->set_room_as_read(current_room); - - Message *read_message = last_visible_timeline_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()); - } - }); + + if(last_timeline_message != -1) { + 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); + size_t last_line_start = room_desc.rfind('\n'); + if(last_line_start != std::string::npos && last_line_start != room_desc.size()) { + ++last_line_start; + size_t last_line_size = room_desc.size() - last_line_start; + if(last_line_size >= 23 && memcmp(&room_desc[last_line_start], "** ", 3) == 0 && memcmp(&room_desc[room_desc.size() - 20], "unread mention(s) **", 20) == 0) + room_desc.erase(room_desc.begin() + last_line_start - 1, room_desc.end()); + } + current_room->body_item->set_description(std::move(room_desc)); + current_room->body_item->set_description_color(sf::Color(179, 179, 179)); + // TODO: Show a line like nheko instead for unread messages, or something else + current_room->body_item->set_title_color(sf::Color::White); + 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; + + matrix_chat_page->set_room_as_read(current_room); + + Message *read_message = static_cast(body_items[last_timeline_message]->userdata); + 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_bottom_cut_off()) { window.draw(more_messages_below_rect); -- cgit v1.2.3