From fd9178b9d500a0b5f30f388f8d419ac386ce87cb Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 17 Oct 2020 00:35:20 +0200 Subject: Matrix: edit/redact the referenced message instead of appending a new message --- src/Body.cpp | 13 ++++-------- src/QuickMedia.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Body.cpp b/src/Body.cpp index 75706c1..9b12f43 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -178,6 +178,7 @@ namespace QuickMedia { assert(item >= 0 && item < (int)items.size()); selected_item = item; prev_selected_item = selected_item; + clamp_selection(); //page_scroll = 0.0f; } @@ -291,21 +292,16 @@ namespace QuickMedia { for(int i = selected_item; i >= 0; --i) { if(items[i]->visible) { selected_item = i; - goto reset_scroll; + return; } } - for(int i = selected_item; i < num_items; ++i) { + for(int i = selected_item + 1; i < num_items; ++i) { if(items[i]->visible) { selected_item = i; - goto reset_scroll; + return; } } - - reset_scroll: - {} - //prev_selected_item = selected_item; - //page_scroll = 0.0f; } void Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size) { @@ -314,7 +310,6 @@ namespace QuickMedia { // TODO: Use a render target for the whole body so all images can be put into one. // TODO: Load thumbnails with more than one thread. - // TODO: Show chapters (rows) that have been read differently to make it easier to see what hasn't been read yet. void Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, const Json::Value &content_progress) { sf::Vector2f scissor_pos = pos; sf::Vector2f scissor_size = size; diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 249f38f..80567f2 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -2891,6 +2891,8 @@ namespace QuickMedia { body_item->author_color = message->user->display_name_color; body_item->userdata = (void*)message.get(); // Note: message has to be valid as long as body_item is used! result_items[i] = std::move(body_item); + if(message->related_event_type == RelatedEventType::REDACTION || message->related_event_type == RelatedEventType::EDIT) + result_items[i]->visible = false; } return result_items; } @@ -3267,6 +3269,53 @@ namespace QuickMedia { return nullptr; }; + // TODO: Optimize with hash map? + auto find_body_items_by_event_id = [](std::shared_ptr *body_items, size_t num_body_items, const std::string &event_id) -> std::shared_ptr { + for(size_t i = 0; i < num_body_items; ++i) { + auto &body_item = body_items[i]; + if(static_cast(body_item->userdata)->event_id == event_id) + return body_item; + } + return nullptr; + }; + + // TODO: What if these never end up referencing events? clean up automatically after a while? + std::unordered_map, Messages> unreferenced_event_by_room; + + auto resolve_unreferenced_events_with_body_items = [&unreferenced_event_by_room, ¤t_room, &find_body_items_by_event_id](std::shared_ptr *body_items, size_t num_body_items) { + auto &unreferenced_events = unreferenced_event_by_room[current_room]; + for(auto it = unreferenced_events.begin(); it != unreferenced_events.end(); ) { + auto &message = *it; + // TODO: Make redacted/edited events as (redacted)/(edited) in the body + if(message->related_event_type == RelatedEventType::REDACTION || message->related_event_type == RelatedEventType::EDIT) { + auto body_item = find_body_items_by_event_id(body_items, num_body_items, message->related_event_id); + if(body_item) { + body_item->set_description(message->body); + it = unreferenced_events.erase(it); + } else { + ++it; + } + } else { + ++it; + } + } + }; + + auto modify_related_messages_in_current_room = [&unreferenced_event_by_room, ¤t_room, &find_body_items_by_event_id, &tabs](Messages &messages) { + auto &unreferenced_events = unreferenced_event_by_room[current_room]; + for(auto &message : messages) { + // TODO: Make redacted/edited events as (redacted)/(edited) in the body + if(message->related_event_type == RelatedEventType::REDACTION || message->related_event_type == RelatedEventType::EDIT) { + auto &body_items = tabs[MESSAGES_TAB_INDEX].body->items; + auto body_item = find_body_items_by_event_id(body_items.data(), body_items.size(), message->related_event_id); + if(body_item) + body_item->set_description(message->body); + else + unreferenced_events.push_back(message); + } + } + }; + while (current_page == PageType::CHAT) { sf::Int32 frame_time_ms = frame_timer.restart().asMilliseconds(); while (window.pollEvent(event)) { @@ -3518,6 +3567,7 @@ namespace QuickMedia { if(matrix->get_all_synced_room_messages(current_room, new_messages) == PluginResult::OK) { tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(new_messages)); tabs[MESSAGES_TAB_INDEX].body->select_last_item(); + modify_related_messages_in_current_room(new_messages); } else { std::string err_msg = "Failed to get messages in room: " + current_room->id; show_notification("QuickMedia", err_msg, Urgency::CRITICAL); @@ -3699,10 +3749,10 @@ namespace QuickMedia { add_new_rooms(sync_result.rooms); auto room_messages_it = sync_result.room_sync_messages.find(current_room); - if(room_messages_it != sync_result.room_sync_messages.end()) + if(room_messages_it != sync_result.room_sync_messages.end()) { add_new_messages_to_current_room(room_messages_it->second); - - //modify_related_messages() + modify_related_messages_in_current_room(room_messages_it->second); + } process_new_room_messages(sync_result.room_sync_messages, !synced); sync_running = false; @@ -3722,12 +3772,16 @@ namespace QuickMedia { size_t num_new_messages = new_messages.size(); if(previous_messages_future_room == current_room && num_new_messages > 0) { BodyItem *selected_item = tabs[MESSAGES_TAB_INDEX].body->get_selected(); - tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(new_messages)); + BodyItems new_body_items = messages_to_body_items(new_messages); + size_t num_new_body_items = new_body_items.size(); + tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(std::move(new_body_items)); if(selected_item) { int selected_item_index = tabs[MESSAGES_TAB_INDEX].body->get_index_by_body_item(selected_item); if(selected_item_index != -1) tabs[MESSAGES_TAB_INDEX].body->set_selected_item(selected_item_index); } + modify_related_messages_in_current_room(new_messages); + resolve_unreferenced_events_with_body_items(tabs[MESSAGES_TAB_INDEX].body->items.data(), num_new_body_items); } fetching_previous_messages_running = false; } -- cgit v1.2.3