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/FileManager.cpp | 2 +- src/plugins/Fourchan.cpp | 2 +- src/plugins/HotExamples.cpp | 2 +- src/plugins/MangaGeneric.cpp | 2 +- src/plugins/Mangadex.cpp | 4 +- src/plugins/Manganelo.cpp | 2 +- src/plugins/Matrix.cpp | 166 ++++++++++++++++++++----------------------- src/plugins/NyaaSi.cpp | 14 ++-- src/plugins/Soundcloud.cpp | 6 +- 9 files changed, 96 insertions(+), 104 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/FileManager.cpp b/src/plugins/FileManager.cpp index f78265b..295b962 100644 --- a/src/plugins/FileManager.cpp +++ b/src/plugins/FileManager.cpp @@ -52,7 +52,7 @@ namespace QuickMedia { set_last_accessed_dir(current_dir); auto body = create_body(); - body->items = std::move(result_items); + body->set_items(std::move(result_items)); result_tabs.push_back(Tab{std::move(body), nullptr, nullptr}); return PluginResult::OK; } diff --git a/src/plugins/Fourchan.cpp b/src/plugins/Fourchan.cpp index c1d7d6a..f7c9910 100644 --- a/src/plugins/Fourchan.cpp +++ b/src/plugins/Fourchan.cpp @@ -365,7 +365,7 @@ namespace QuickMedia { } auto body = create_body(false); - body->items = std::move(result_items); + body->set_items(std::move(result_items)); result_tabs.push_back(Tab{std::move(body), std::make_unique(program, board_id, url), nullptr}); return PluginResult::OK; } diff --git a/src/plugins/HotExamples.cpp b/src/plugins/HotExamples.cpp index 02f1217..29e0110 100644 --- a/src/plugins/HotExamples.cpp +++ b/src/plugins/HotExamples.cpp @@ -132,7 +132,7 @@ namespace QuickMedia { quickmedia_html_search_deinit(&html_search); auto body = create_body(); - body->items = std::move(result_items); + body->set_items(std::move(result_items)); result_tabs.push_back({ std::move(body), std::make_unique(program, title + " code examples"), create_search_bar("Search...", SEARCH_DELAY_FILTER) }); return PluginResult::OK; } diff --git a/src/plugins/MangaGeneric.cpp b/src/plugins/MangaGeneric.cpp index 4668970..90da0c2 100644 --- a/src/plugins/MangaGeneric.cpp +++ b/src/plugins/MangaGeneric.cpp @@ -368,7 +368,7 @@ namespace QuickMedia { return PluginResult::ERR; auto body = create_body(); - body->items = std::move(chapters_items); + body->set_items(std::move(chapters_items)); result_tabs.push_back(Tab{std::move(body), std::make_unique(program, title, url, manga_id_extractor, service_name, website_url, &list_page_query, fail_on_http_error), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); for(auto &it : creators) { diff --git a/src/plugins/Mangadex.cpp b/src/plugins/Mangadex.cpp index 477608e..98683c1 100644 --- a/src/plugins/Mangadex.cpp +++ b/src/plugins/Mangadex.cpp @@ -307,7 +307,9 @@ namespace QuickMedia { PluginResult MangadexSearchPage::submit(const std::string &title, const std::string &url, std::vector &result_tabs) { chapter_image_urls.clear(); auto body = create_body(); - get_chapters_for_manga(this, url, 0, body->items, chapter_image_urls); + BodyItems body_items; + get_chapters_for_manga(this, url, 0, body_items, chapter_image_urls); + body->set_items(std::move(body_items)); result_tabs.push_back(Tab{std::move(body), std::make_unique(program, this, title, url), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); return PluginResult::OK; } diff --git a/src/plugins/Manganelo.cpp b/src/plugins/Manganelo.cpp index e0517dd..d3d7bfa 100644 --- a/src/plugins/Manganelo.cpp +++ b/src/plugins/Manganelo.cpp @@ -93,7 +93,7 @@ namespace QuickMedia { return PluginResult::ERR; auto chapters_body = page->create_body(); - chapters_body->items = std::move(chapters_items); + chapters_body->set_items(std::move(chapters_items)); result_tabs.push_back(Tab{std::move(chapters_body), std::make_unique(page->program, title, url), page->create_search_bar("Search...", SEARCH_DELAY_FILTER)}); // TODO: Fix. Doesn't work because manganelo changes creator url format 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); diff --git a/src/plugins/NyaaSi.cpp b/src/plugins/NyaaSi.cpp index ccf027d..8e55e62 100644 --- a/src/plugins/NyaaSi.cpp +++ b/src/plugins/NyaaSi.cpp @@ -134,12 +134,12 @@ namespace QuickMedia { return body_item; } - static void sort_page_create_body_items(BodyItems &body_items, NyaaSiSortType sort_type) { + static void sort_page_create_body_items(Body *body, NyaaSiSortType sort_type) { for(size_t i = 0; i < sort_type_names.size(); ++i) { std::string prefix = " "; if((NyaaSiSortType)i == sort_type) prefix = "* "; - body_items.push_back(create_sort_body_item(prefix + sort_type_names[i], (NyaaSiSortType)i)); + body->append_item(create_sort_body_item(prefix + sort_type_names[i], (NyaaSiSortType)i)); } } @@ -294,12 +294,12 @@ namespace QuickMedia { auto search_page = std::make_unique(program, strip(title), url, std::move(domain)); NyaaSiSearchPage *search_page_p = search_page.get(); auto body = create_body(); - body->items = std::move(result_items); + body->set_items(std::move(result_items)); result_tabs.push_back(Tab{std::move(body), std::move(search_page), create_search_bar("Search...", 500)}); auto sort_order_page_body = create_body(); Body *sort_order_page_body_p = sort_order_page_body.get(); - sort_page_create_body_items(sort_order_page_body->items, NyaaSiSortType::UPLOAD_DATE_DESC); + sort_page_create_body_items(sort_order_page_body_p, NyaaSiSortType::UPLOAD_DATE_DESC); result_tabs.push_back(Tab{std::move(sort_order_page_body), std::make_unique(program, sort_order_page_body_p, search_page_p), nullptr}); return PluginResult::OK; } @@ -486,7 +486,7 @@ namespace QuickMedia { return PluginResult::ERR; auto body = create_body(); - body->items = std::move(result_items); + body->set_items(std::move(result_items)); result_tabs.push_back(Tab{std::move(body), std::make_unique(program), nullptr}); return PluginResult::OK; } @@ -499,8 +499,8 @@ namespace QuickMedia { PluginResult NyaaSiSortOrderPage::submit(const std::string&, const std::string&, std::vector&) { const NyaaSiSortType sort_type = (NyaaSiSortType)(size_t)submit_body_item->userdata; - body->items.clear(); - sort_page_create_body_items(body->items, sort_type); + body->clear_items(); + sort_page_create_body_items(body, sort_type); search_page->set_sort_type(sort_type); search_page->needs_refresh = true; return PluginResult::OK; diff --git a/src/plugins/Soundcloud.cpp b/src/plugins/Soundcloud.cpp index 7079e46..f20cf7d 100644 --- a/src/plugins/Soundcloud.cpp +++ b/src/plugins/Soundcloud.cpp @@ -247,7 +247,7 @@ namespace QuickMedia { if(url == "track") { SoundcloudPlaylist *playlist = static_cast(submit_body_item->extra.get()); auto body = create_body(false, true); - body->items = playlist->tracks; + body->set_items(playlist->tracks); result_tabs.push_back(Tab{std::move(body), std::make_unique(program, playlist, title), nullptr}); } else if(url.find("/stream/users/") != std::string::npos) { std::string query_url = url + "?client_id=" + client_id + "&limit=20&offset=0&linked_partitioning=1&app_version=1616689516&app_locale=en"; @@ -258,7 +258,9 @@ namespace QuickMedia { auto body = create_body(false, true); std::string next_href; - PluginResult pr = parse_user_page(json_root, body->items, next_href); + BodyItems body_items; + PluginResult pr = parse_user_page(json_root, body_items, next_href); + body->set_items(std::move(body_items)); if(pr != PluginResult::OK) return pr; result_tabs.push_back(Tab{std::move(body), std::make_unique(program, title, url, std::move(next_href)), nullptr}); -- cgit v1.2.3