aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-05-31 04:33:28 +0200
committerdec05eba <dec05eba@protonmail.com>2022-05-31 04:33:28 +0200
commit3586e3b510ef6828ab44dad1467f18ef4f2d7e2b (patch)
tree5e9eed17378fe65ef594cdac55acd5899b66ae8a
parent6e9bfd6571adf151e4e7fe4cb63f731314ebeff6 (diff)
Youtube: merge search page and recommended page (show recommended if search field empty)
-rw-r--r--include/QuickMedia.hpp5
-rw-r--r--plugins/Youtube.hpp3
-rw-r--r--src/QuickMedia.cpp56
-rw-r--r--src/plugins/Youtube.cpp15
4 files changed, 42 insertions, 37 deletions
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index c1df4ed..b5570da 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -69,6 +69,7 @@ namespace QuickMedia {
bool fetching_next_page_running = false;
bool fetching_next_page_failed = false;
bool search_suggestion_submitted = false;
+ bool card_view = false;
int fetched_page = 0;
mgl::Text search_result_text;
AsyncTask<FetchResult> fetch_future;
@@ -110,6 +111,10 @@ namespace QuickMedia {
Json::Value load_history_json();
+ Json::Value load_recommended_json(const char *plugin_name);
+ void fill_recommended_items_from_json(const char *plugin_name, const Json::Value &recommended_json, BodyItems &body_items);
+ void save_recommendations_from_related_videos(const char *plugin_name, const std::string &video_url, const std::string &video_title, const BodyItems &related_media_body_items);
+
void set_clipboard(const std::string &str);
private:
void init(mgl::WindowHandle parent_window, std::string &program_path);
diff --git a/plugins/Youtube.hpp b/plugins/Youtube.hpp
index 8844c5b..78fc40f 100644
--- a/plugins/Youtube.hpp
+++ b/plugins/Youtube.hpp
@@ -39,6 +39,8 @@ namespace QuickMedia {
// If false is returned from |active_handler|, then this function is cancelled.
bool youtube_custom_redirect(std::string &video_url, std::string &audio_url, int64_t &video_content_length, int64_t &audio_content_length, std::function<bool()> active_handler);
+ // fill_recommended_items_from_json(plugin_name, load_recommended_json(plugin_name), result_items);
+
class YoutubeSearchPage : public LazyFetchPage {
public:
YoutubeSearchPage(Program *program, std::string video_id = "") : LazyFetchPage(program), video_id(std::move(video_id)) {}
@@ -51,6 +53,7 @@ namespace QuickMedia {
PluginResult submit_suggestion(const SubmitArgs &args, BodyItems &result_items) override;
PluginResult lazy_fetch(BodyItems &result_items) override;
bool lazy_fetch_is_loader() override { return true; }
+ bool reload_on_page_change() override { return true; }
private:
PluginResult search_get_continuation(const std::string &url, const std::string &continuation_token, BodyItems &result_items);
private:
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index e8fee28..494e03d 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -52,6 +52,7 @@
#include <limits.h>
#include <sys/stat.h>
#include <cmath>
+#include <random>
#include <mglpp/graphics/Rectangle.hpp>
#include <mglpp/graphics/Sprite.hpp>
@@ -227,9 +228,6 @@ static void set_window_icon(Display *display, Window window, const std::string &
}
namespace QuickMedia {
- static Json::Value load_recommended_json(const char *plugin_name);
- static void fill_recommended_items_from_json(const char *plugin_name, const Json::Value &recommended_json, BodyItems &body_items);
-
enum class HistoryType {
YOUTUBE,
MANGA
@@ -266,28 +264,6 @@ namespace QuickMedia {
bool local_thumbnail;
};
- class RecommendedPage : public LazyFetchPage {
- public:
- RecommendedPage(Program *program, Page *search_page, const char *plugin_name) :
- LazyFetchPage(program), search_page(search_page), plugin_name(plugin_name) {}
-
- const char* get_title() const override { return "Recommended"; }
-
- PluginResult submit(const SubmitArgs &args, std::vector<Tab> &result_tabs) override {
- return search_page->submit(args, result_tabs);
- }
-
- PluginResult lazy_fetch(BodyItems &result_items) override {
- fill_recommended_items_from_json(plugin_name, load_recommended_json(plugin_name), result_items);
- return PluginResult::OK;
- }
-
- bool reload_on_page_change() override { return true; }
- private:
- Page *search_page;
- const char *plugin_name;
- };
-
using OptionsPageHandler = std::function<void()>;
class OptionsPage : public Page {
@@ -1275,10 +1251,7 @@ namespace QuickMedia {
if(youtube_url.empty()) {
start_tab_index = 1;
tabs.push_back(Tab{create_body(false, true), std::make_unique<YoutubeSubscriptionsPage>(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
- tabs.push_back(Tab{create_body(false, false), std::make_unique<YoutubeSearchPage>(this), create_search_bar("Search...", 100)});
-
- auto recommended_page = std::make_unique<RecommendedPage>(this, tabs.back().page.get(), plugin_name);
- tabs.push_back(Tab{create_body(false, true), std::move(recommended_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+ tabs.push_back(Tab{create_body(false, true), std::make_unique<YoutubeSearchPage>(this), create_search_bar("Search...", 100)});
auto history_body = create_body(false, true);
auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::YOUTUBE);
@@ -1475,7 +1448,7 @@ namespace QuickMedia {
return video_history_filepath.join(plugin_name).append(".json");
}
- Json::Value load_recommended_json(const char *plugin_name) {
+ Json::Value Program::load_recommended_json(const char *plugin_name) {
Path recommended_filepath = get_recommended_filepath(plugin_name);
Json::Value json_result;
if(!read_file_as_json(recommended_filepath, json_result) || !json_result.isObject())
@@ -1483,7 +1456,7 @@ namespace QuickMedia {
return json_result;
}
- void fill_recommended_items_from_json(const char *plugin_name, const Json::Value &recommended_json, BodyItems &body_items) {
+ void Program::fill_recommended_items_from_json(const char *plugin_name, const Json::Value &recommended_json, BodyItems &body_items) {
assert(recommended_json.isObject());
const int64_t recommendations_autodelete_period = 60*60*24*20; // 20 days
@@ -1574,10 +1547,11 @@ namespace QuickMedia {
break;
}
- std::random_shuffle(body_items.begin(), body_items.end());
+ const auto seed = std::chrono::system_clock::now().time_since_epoch().count();
+ std::shuffle(body_items.begin(), body_items.end(), std::default_random_engine(seed));
}
- static void save_recommendations_from_related_videos(const char *plugin_name, const std::string &video_url, const std::string &video_title, const BodyItems &related_media_body_items) {
+ void Program::save_recommendations_from_related_videos(const char *plugin_name, const std::string &video_url, const std::string &video_title, const BodyItems &related_media_body_items) {
std::string video_id;
if(!youtube_url_extract_id(video_url, video_id)) {
std::string err_msg = "Failed to extract id of youtube url ";
@@ -2044,6 +2018,7 @@ namespace QuickMedia {
if(tab.body->attach_side == AttachSide::BOTTOM)
tab.body->select_last_item();
tab.page->on_navigate_to_page(tab.body.get());
+
}
Tabs ui_tabs(&rounded_rectangle_shader);
@@ -2063,6 +2038,7 @@ namespace QuickMedia {
for(size_t i = 0; i < tabs.size(); ++i) {
TabAssociatedData data;
data.search_result_text = mgl::Text("", *FontLoader::get_font(FontLoader::FontType::LATIN, 30 * get_config().scale * get_config().font_scale));
+ data.card_view = tabs[i].body ? tabs[i].body->card_view : false;
tab_associated_data.push_back(std::move(data));
}
@@ -2103,7 +2079,7 @@ namespace QuickMedia {
tab_associated_data[selected_tab].search_text_updated = false;
}
- auto plugin_submit_handler = [&tabs, selected_tab, &selected_item, &search_text, &new_tabs, &new_body_items, search_suggestion_submitted]() {
+ auto plugin_submit_handler = [&]() {
SubmitArgs submit_args;
submit_args.title = selected_item ? selected_item->get_title() : search_text;
submit_args.url = selected_item ? selected_item->url : search_text;
@@ -2112,6 +2088,7 @@ namespace QuickMedia {
submit_args.extra = selected_item ? selected_item->extra : nullptr;
if(tabs[selected_tab].page->search_is_suggestion() && !search_suggestion_submitted) {
+ tabs[selected_tab].body->card_view = tab_associated_data[selected_tab].card_view;
PluginResult plugin_result = tabs[selected_tab].page->submit_suggestion(submit_args, new_body_items);
return plugin_result == PluginResult::OK;
} else {
@@ -2176,7 +2153,8 @@ namespace QuickMedia {
for(size_t i = 0; i < tabs.size(); ++i) {
tabs[i].body->clear_cache();
- if(tabs[i].page->is_lazy_fetch_page() && static_cast<LazyFetchPage*>(tabs[i].page.get())->reload_on_page_change()) {
+ const bool lazy_update = tabs[i].page->search_is_filter() || (tabs[i].search_bar && tabs[i].search_bar->get_text().empty());
+ if(tabs[i].page->is_lazy_fetch_page() && static_cast<LazyFetchPage*>(tabs[i].page.get())->reload_on_page_change() && lazy_update) {
tab_associated_data[i].lazy_fetch_finished = false;
tab_associated_data[i].fetched_page = 0;
const BodyItem *selected_item = tabs[i].body->get_selected();
@@ -2636,6 +2614,14 @@ namespace QuickMedia {
std::string update_search_text = associated_data.update_search_text;
if(!tabs[i].page->search_is_suggestion() || associated_data.search_suggestion_submitted)
tabs[i].body->clear_items();
+
+ if(tabs[i].page->search_is_suggestion() && tabs[i].body) {
+ if(update_search_text.empty())
+ tabs[i].body->card_view = tab_associated_data[selected_tab].card_view;
+ else
+ tabs[i].body->card_view = false;
+ }
+
associated_data.search_text_updated = false;
associated_data.fetch_status = FetchStatus::LOADING;
associated_data.fetch_type = FetchType::SEARCH;
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index 3177f4d..65db3b1 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -9,6 +9,7 @@
#include "../../include/Theme.hpp"
#include "../../include/Config.hpp"
#include "../../plugins/WatchProgress.hpp"
+#include "../../include/QuickMedia.hpp"
#include <optional>
#include <json/reader.h>
extern "C" {
@@ -784,8 +785,14 @@ namespace QuickMedia {
}
SearchResult YoutubeSearchPage::search(const std::string &str, BodyItems &result_items) {
- if(str.empty())
+ continuation_token.clear();
+ current_page = 0;
+ added_videos.clear();
+
+ if(str.empty()) {
+ program->fill_recommended_items_from_json("youtube", program->load_recommended_json("youtube"), result_items);
return SearchResult::OK;
+ }
// TODO: Find this search url from youtube.com/... searchbox.js, and the url to that script from youtube.com/ html
std::string url = "https://suggestqueries-clients6.youtube.com/complete/search?client=youtube&hl=en&gl=us&sugexp=rdcfrc%2Ccfro%3D1%2Cfp.cfr%3D1&gs_rn=64&gs_ri=youtube&ds=yt&cp=34&gs_id=f&xhr=t&xssi=t&q=";
@@ -929,7 +936,11 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult YoutubeSearchPage::lazy_fetch(BodyItems&) {
+ PluginResult YoutubeSearchPage::lazy_fetch(BodyItems &result_items) {
+ continuation_token.clear();
+ current_page = 0;
+ added_videos.clear();
+ program->fill_recommended_items_from_json("youtube", program->load_recommended_json("youtube"), result_items);
get_cookies();
return PluginResult::OK;
}