diff options
-rw-r--r-- | plugins/Youtube.hpp | 2 | ||||
-rw-r--r-- | src/Body.cpp | 12 | ||||
-rw-r--r-- | src/plugins/Youtube.cpp | 30 |
3 files changed, 39 insertions, 5 deletions
diff --git a/plugins/Youtube.hpp b/plugins/Youtube.hpp index 25a97c3..e8cc2c2 100644 --- a/plugins/Youtube.hpp +++ b/plugins/Youtube.hpp @@ -9,6 +9,6 @@ namespace QuickMedia { SuggestionResult update_search_suggestions(const std::string &text, std::vector<std::unique_ptr<BodyItem>> &result_items) override; std::vector<std::unique_ptr<BodyItem>> get_related_media(const std::string &url) override; bool search_suggestions_has_thumbnails() const override { return false; } - bool search_results_has_thumbnails() const override { return false; } + bool search_results_has_thumbnails() const override { return true; } }; }
\ No newline at end of file diff --git a/src/Body.cpp b/src/Body.cpp index 52f3105..c9fbc89 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -110,12 +110,11 @@ namespace QuickMedia { draw(window, pos, size, empty_object); } - // TODO: Skip drawing the rows that are outside the window. // TODO: Use a render target for the whole body so all images can be put into one. - // TODO: Only load images once they are visible on the screen. + // TODO: Unload thumbnails once they are no longer visible on the screen. // TODO: Load thumbnails with more than one thread. // TODO: Show chapters (rows) that have been read differently to make it easier to see what - // needs hasn't been read yet. + // hasn't been read yet. void Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, const Json::Value &content_progress) { const float font_height = title_text.getCharacterSize() + 8.0f; const float image_height = 100.0f; @@ -159,10 +158,15 @@ namespace QuickMedia { ++visible_rows; } + auto window_size = window.getSize(); + for(int i = first_visible_item + 1; i < num_items; ++i) { const auto &item = items[i]; - assert(items.size() == item_thumbnail_textures.size()); auto &item_thumbnail = item_thumbnail_textures[i]; + + if(pos.y >= window_size.y) + return; + if(!item->visible) continue; diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp index 67a47e4..40d545c 100644 --- a/src/plugins/Youtube.cpp +++ b/src/plugins/Youtube.cpp @@ -8,6 +8,10 @@ namespace QuickMedia { return strncmp(str, begin_with, strlen(begin_with)) == 0; } + static bool contains(const char *str, const char *substr) { + return strstr(str, substr); + } + SearchResult Youtube::search(const std::string &text, std::vector<std::unique_ptr<BodyItem>> &result_items, Page &next_page) { next_page = Page::SEARCH_RESULT; std::string url = "https://youtube.com/results?search_query="; @@ -17,6 +21,12 @@ namespace QuickMedia { if(download_to_string(url, website_data) != DownloadResult::OK) return SearchResult::NET_ERR; + struct ItemData { + std::vector<std::unique_ptr<BodyItem>> *result_items; + size_t index; + }; + ItemData item_data = { &result_items, 0 }; + QuickMediaHtmlSearch html_search; int result = quickmedia_html_search_init(&html_search, website_data.c_str()); if(result != 0) @@ -34,6 +44,26 @@ namespace QuickMedia { result_items->push_back(std::move(item)); } }, &result_items); + if(result != 0) + goto cleanup; + + result = quickmedia_html_find_nodes_xpath(&html_search, "//span[class=\"yt-thumb-simple\"]//img", + [](QuickMediaHtmlNode *node, void *userdata) { + ItemData *item_data = (ItemData*)userdata; + if(item_data->index >= item_data->result_items->size()) + return; + + const char *src = quickmedia_html_node_get_attribute_value(node, "src"); + const char *data_thumb = quickmedia_html_node_get_attribute_value(node, "data-thumb"); + + if(src && contains(src, "i.ytimg.com/")) { + (*item_data->result_items)[item_data->index]->thumbnail_url = src; + ++item_data->index; + } else if(data_thumb && contains(data_thumb, "i.ytimg.com/")) { + (*item_data->result_items)[item_data->index]->thumbnail_url = data_thumb; + ++item_data->index; + } + }, &item_data); cleanup: quickmedia_html_search_deinit(&html_search); |