aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-05-28 16:32:04 +0200
committerdec05eba <dec05eba@protonmail.com>2021-05-28 16:32:04 +0200
commit517119dfc65a185062b473499988ddea13959fcd (patch)
tree5fc269b0e31dead3b0d2820719eb7a2bd438696e
parentd3791678aafc06e6ac278e1e1fd9a04bb32223a6 (diff)
Set correct read marker if the latest message is an edit
-rw-r--r--src/QuickMedia.cpp92
1 files 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, &current_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, &current_room, &me, &fetch_message_future, &tabs, &fetch_body_item, &fetch_message_tab, MESSAGES_TAB_INDEX](BodyItem *body_item) {
Message *message = static_cast<Message*>(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<Message*>(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<void>([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<Message*>(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<void>([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);