From 6c85194c3b1baef0eaa011c4f1b8e48e11860f45 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 3 Aug 2021 15:06:57 +0200 Subject: Make body items private, add accessor functions This allows body to automatically update dirty state (and other states). Correctly format newlines in codeblocks in matrix. --- src/plugins/Matrix.cpp | 166 +++++++++++++++++++++++-------------------------- 1 file changed, 77 insertions(+), 89 deletions(-) (limited to 'src/plugins/Matrix.cpp') diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 18a76eb..f072a27 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -506,26 +506,26 @@ namespace QuickMedia { }); } - static void insert_room_body_item_by_timestamp(BodyItems &body_items, std::shared_ptr new_body_item) { + static void insert_room_body_item_by_timestamp(Body *body, std::shared_ptr new_body_item) { RoomData *new_room = static_cast(new_body_item->userdata); - for(auto it = body_items.begin(), end = body_items.end(); it != end; ++it) { - RoomData *room = static_cast((*it)->userdata); - if(new_room->last_message_timestamp >= room->last_message_timestamp) { - body_items.insert(it, std::move(new_body_item)); - return; - } - } - body_items.push_back(std::move(new_body_item)); + const int insert_index = body->find_item_index([new_room](std::shared_ptr &body_item) { + RoomData *room = static_cast(body_item->userdata); + return new_room->last_message_timestamp >= room->last_message_timestamp; + }); + + if(insert_index == -1) + body->append_item(std::move(new_body_item)); + else + body->insert_item(std::move(new_body_item), insert_index); } + // TODO: Optimize void body_set_selected_item_by_url(Body *body, const std::string &url) { - for(size_t i = 0; i < body->items.size(); ++i) { - if(body->items[i]->url == url) { - body->select_first_item(); - body->set_selected_item(i, false); - return; - } - } + const int found_item_index = body->find_item_index([&url](std::shared_ptr &body_item) { + return body_item->url == url; + }); + if(found_item_index != -1) + body->set_selected_item(found_item_index, false); } void MatrixQuickMedia::clear_data() { @@ -658,12 +658,8 @@ namespace QuickMedia { return PluginResult::OK; } - void MatrixRoomsPage::on_navigate_to_page(Body *body) { - body->items_set_dirty(true); - } - void MatrixRoomsPage::add_body_item(std::shared_ptr body_item) { - insert_room_body_item_by_timestamp(body->items, body_item); + insert_room_body_item_by_timestamp(body, body_item); } void MatrixRoomsPage::move_room_to_top(RoomData *room) { @@ -678,28 +674,25 @@ namespace QuickMedia { if(room_body_index == selected_item) return; - for(size_t i = 0; i < body->items.size(); ++i) { - RoomData *room_i = static_cast(body->items[i]->userdata); + for(size_t i = 0; i < body->get_num_items(); ++i) { + RoomData *room_i = static_cast(body->get_item_by_index(i)->userdata); if((int)i == room_body_index) return; if((int)i != selected_item && room_i && room->last_message_timestamp >= room_i->last_message_timestamp) { - auto body_item_to_insert = body->items[room_body_index]; - body->items.erase(body->items.begin() + room_body_index); - if(room_body_index >= (int)i) - body->items.insert(body->items.begin() + i, std::move(body_item_to_insert)); - else - body->items.insert(body->items.begin() + (i - 1), std::move(body_item_to_insert)); - if((int)i < selected_item && room_body_index > selected_item && body->items.size() > 1 && i != body->items.size() - 1) { + body->move_item(room_body_index, i); + if((int)i < selected_item && room_body_index > selected_item && body->get_num_items() > 1 && i != body->get_num_items() - 1) body->select_next_item(); - } + return; } } } void MatrixRoomsPage::remove_body_item_by_room_id(const std::string &room_id) { - remove_body_item_by_url(body->items, room_id); + body->erase_item([&room_id](std::shared_ptr &body_item) { + return body_item->url == room_id; + }); if(current_chat_page && current_chat_page->room_id == room_id) { program->set_go_to_previous_page(); body->select_first_item(); @@ -731,9 +724,10 @@ namespace QuickMedia { auto body = create_body(true); Body *body_ptr = body.get(); TagData &tag_data = tag_body_items_by_name[url]; - body->items = tag_data.room_body_items; + BodyItems room_body_items = tag_data.room_body_items; + sort_room_body_items(room_body_items); + body->set_items(std::move(room_body_items)); //BodyItem *selected_item = body->get_selected(); - sort_room_body_items(body->items); //body_set_selected_item(body.get(), selected_item); auto search_bar = create_search_bar("Search...", SEARCH_DELAY_FILTER); auto rooms_page = std::make_unique(program, body_ptr, tag_data.tag_item->get_title(), this, search_bar.get()); @@ -742,10 +736,6 @@ namespace QuickMedia { return PluginResult::OK; } - void MatrixRoomTagsPage::on_navigate_to_page(Body *body) { - body->items_set_dirty(true); - } - void MatrixRoomTagsPage::add_room_body_item_to_tag(std::shared_ptr body_item, const std::string &tag) { TagData *tag_data; auto tag_body_it = tag_body_items_by_name.find(tag); @@ -759,7 +749,7 @@ namespace QuickMedia { tag_body_items_by_name.insert(std::make_pair(tag, TagData{tag_body_item, {}})); // TODO: Sort by tag priority body->apply_search_filter_for_item(tag_body_item.get()); - body->items.push_back(tag_body_item); + body->append_item(tag_body_item); tag_data = &tag_body_items_by_name[tag]; tag_data->tag_item = tag_body_item; } @@ -789,9 +779,10 @@ namespace QuickMedia { tag_body_it->second.room_body_items.erase(room_body_item_it); if(tag_body_it->second.room_body_items.empty()) { - auto room_body_item_it = std::find(body->items.begin(), body->items.end(), tag_body_it->second.tag_item); - if(room_body_item_it != body->items.end()) - body->items.erase(room_body_item_it); + const auto &tag_item = tag_body_it->second.tag_item; + body->erase_item([&tag_item](std::shared_ptr &body_item) { + return body_item == tag_item; + }); tag_body_items_by_name.erase(tag_body_it); } } @@ -831,8 +822,8 @@ namespace QuickMedia { PluginResult MatrixInvitesPage::submit(const std::string &title, const std::string &url, std::vector &result_tabs) { auto body = create_body(); - body->items.push_back(BodyItem::create("Accept")); - body->items.push_back(BodyItem::create("Decline")); + body->append_item(BodyItem::create("Accept")); + body->append_item(BodyItem::create("Decline")); result_tabs.push_back(Tab{std::move(body), std::make_unique(program, matrix, this, url, "Invite to " + title), nullptr}); return PluginResult::OK; } @@ -864,16 +855,19 @@ namespace QuickMedia { // TODO: Insert in reverse order (to show the latest invite at the top?) body->apply_search_filter_for_item(body_item.get()); body->insert_item_by_timestamp(std::move(body_item)); - if(body->items.size() != prev_invite_count) { - prev_invite_count = body->items.size(); - title = "Invites (" + std::to_string(body->items.size()) + ")"; + if(body->get_num_items() != prev_invite_count) { + prev_invite_count = body->get_num_items(); + title = "Invites (" + std::to_string(body->get_num_items()) + ")"; } } void MatrixInvitesPage::remove_body_item_by_room_id(const std::string &room_id) { - if(remove_body_item_by_url(body->items, room_id)) { - prev_invite_count = body->items.size(); - title = "Invites (" + std::to_string(body->items.size()) + ")"; + const bool item_removed = body->erase_item([&room_id](std::shared_ptr &body_item) { + return body_item->url == room_id; + }); + if(item_removed) { + prev_invite_count = body->get_num_items(); + title = "Invites (" + std::to_string(body->get_num_items()) + ")"; } } @@ -908,8 +902,7 @@ namespace QuickMedia { body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE; body_item->thumbnail_size = sf::Vector2i(32, 32); - users_body->apply_search_filter_for_item(body_item.get()); - users_body->items.push_back(std::move(body_item)); + users_body->append_item(std::move(body_item)); } void MatrixChatPage::add_user(MatrixEventUserInfo user_info) { @@ -924,12 +917,9 @@ namespace QuickMedia { return; // TODO: Optimize - for(auto it = users_body->items.begin(), end = users_body->items.end(); it != end; ++it) { - if((*it)->url == user_info.user_id) { - users_body->items.erase(it); - return; - } - } + users_body->erase_item([&user_info](std::shared_ptr &it) { + return it->url == user_info.user_id; + }); } void MatrixChatPage::set_user_info(MatrixEventUserInfo user_info) { @@ -937,32 +927,25 @@ namespace QuickMedia { return; // TODO: Optimize - for(auto it = users_body->items.begin(), end = users_body->items.end(); it != end; ++it) { - if((*it)->url == user_info.user_id) { - if(user_info.avatar_url) - (*it)->thumbnail_url = user_info.avatar_url.value(); - - if(user_info.display_name) { - std::string display_name; - if(user_info.display_name.value().empty()) - display_name = user_info.user_id; - else - display_name = user_info.display_name.value(); - - (*it)->set_author(extract_first_line_remove_newline_elipses(display_name, AUTHOR_MAX_LENGTH)); - - //auto user_body_item = *it; - //users_body->items.erase(it); - - // TODO: extract_first_line_remove_newline_elipses(room->get_user_display_name(message->user), AUTHOR_MAX_LENGTH), - // But that should be done in Text because we need author to be 100% the same as in the input to reorder users - users_body->apply_search_filter_for_item(it->get()); - //size_t insert_index = get_body_item_sorted_insert_position_by_author(users_body->items, user_body_item->get_author(), 0); - //users_body->items.insert(users_body->items.begin() + insert_index, std::move(user_body_item)); - } + auto user_body_item = users_body->find_item([&user_info](std::shared_ptr &it) { + return it->url == user_info.user_id; + }); - return; - } + if(!user_body_item) + return; + + if(user_info.avatar_url) + user_body_item->thumbnail_url = user_info.avatar_url.value(); + + if(user_info.display_name) { + const std::string *display_name; + if(user_info.display_name.value().empty()) + display_name = &user_info.user_id; + else + display_name = &user_info.display_name.value(); + + user_body_item->set_author(extract_first_line_remove_newline_elipses(*display_name, AUTHOR_MAX_LENGTH)); + users_body->apply_search_filter_for_item(user_body_item.get()); } } @@ -978,7 +961,7 @@ namespace QuickMedia { } size_t MatrixChatPage::get_num_users_in_current_room() const { - return users_body ? users_body->items.size() : 0; + return users_body ? users_body->get_num_items() : 0; } void MatrixChatPage::set_room_as_read(RoomData *room) { @@ -1095,19 +1078,20 @@ namespace QuickMedia { //int prev_selected_item = notifications_body->get_selected_item(); //notifications_body->items.push_back(notification_to_body_item(notifications_body, notification)); //notifications_body->set_selected_item(prev_selected_item - 1); - notifications_body->items.insert(notifications_body->items.begin(), notification_to_body_item(notifications_body, notification)); + notifications_body->prepend_item(notification_to_body_item(notifications_body, notification)); notifications_body->select_next_item(); } + // TODO: Only loop unread items void MatrixNotificationsPage::set_room_as_read(RoomData *room) { - for(auto &body_item : notifications_body->items) { + notifications_body->for_each_item([room](std::shared_ptr &body_item) { NotificationsExtraData *extra_data = static_cast(body_item->extra.get()); if(!extra_data->read && extra_data->room == room) { extra_data->read = true; body_item->set_author_color(get_current_theme().text_color); body_item->set_description_color(get_current_theme().text_color); } - } + }); } SearchResult MatrixInviteUserPage::search(const std::string &str, BodyItems &result_items) { @@ -3036,8 +3020,12 @@ namespace QuickMedia { bool is_inside_code_block = false; bool is_first_line = true; string_split(body, '\n', [this, room, &formatted_body, &is_inside_code_block, &is_first_line](const char *str, size_t size){ - if(!is_first_line) - formatted_body += "
"; + if(!is_first_line) { + if(is_inside_code_block) + formatted_body += '\n'; + else + formatted_body += "
"; + } std::string line_str(str, size); html_escape_sequences(line_str); -- cgit v1.2.3