diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-08-26 01:10:40 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-08-26 01:10:40 +0200 |
commit | e62b707603ec00fc5192bf702b4bca0ed77501e6 (patch) | |
tree | 49e71f28a0ef42ab10872561f72b0e51d86cced6 /src/QuickMedia.cpp | |
parent | 0a26a319b241978ee317bbe768eb61c4eb7a39d9 (diff) |
Add ctrl+b to bookmark manga
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r-- | src/QuickMedia.cpp | 165 |
1 files changed, 128 insertions, 37 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 1bc260c..acc1770 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -293,6 +293,7 @@ namespace QuickMedia { return PluginResult::OK; } bool reload_on_page_change() override { return true; } + const char* get_bookmark_name() const override { return search_page->get_bookmark_name(); } private: Page *search_page; HistoryType history_type; @@ -1118,51 +1119,81 @@ namespace QuickMedia { }); tabs.push_back(Tab{std::move(pipe_body), std::make_unique<PipePage>(this, "Select plugin to launch"), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); } else if(strcmp(plugin_name, "manganelo") == 0) { - tabs.push_back(Tab{create_body(false, true), std::make_unique<ManganeloSearchPage>(this), create_search_bar("Search...", 400)}); + auto search_page = std::make_unique<ManganeloSearchPage>(this); + + tabs.push_back(Tab{create_body(), std::make_unique<BookmarksPage>(this, search_page.get()), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 400)}); auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA); tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + + start_tab_index = 1; } else if(strcmp(plugin_name, "manganelos") == 0) { auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "http://manganelos.com/"); add_manganelos_handlers(search_page.get()); - tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 400)}); + + tabs.push_back(Tab{create_body(), std::make_unique<BookmarksPage>(this, search_page.get()), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)}); auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA); tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + + start_tab_index = 1; } else if(strcmp(plugin_name, "mangatown") == 0) { auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "https://www.mangatown.com/"); add_mangatown_handlers(search_page.get()); - tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 400)}); + + tabs.push_back(Tab{create_body(), std::make_unique<BookmarksPage>(this, search_page.get()), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)}); auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA); tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + + start_tab_index = 1; } else if(strcmp(plugin_name, "mangakatana") == 0) { auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "https://mangakatana.com/", false); add_mangakatana_handlers(search_page.get()); + + tabs.push_back(Tab{create_body(), std::make_unique<BookmarksPage>(this, search_page.get()), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)}); auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA); tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + + start_tab_index = 1; } else if(strcmp(plugin_name, "mangadex") == 0) { - tabs.push_back(Tab{create_body(), std::make_unique<MangadexSearchPage>(this), create_search_bar("Search...", 400)}); - upgrade_legacy_mangadex_ids(this, tabs.back().page.get()); + auto search_page = std::make_unique<MangadexSearchPage>(this); + upgrade_legacy_mangadex_ids(this, search_page.get()); + + tabs.push_back(Tab{create_body(), std::make_unique<BookmarksPage>(this, search_page.get()), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)}); auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA); tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + + start_tab_index = 1; } else if(strcmp(plugin_name, "readm") == 0) { auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "https://readm.org/"); add_readm_handlers(search_page.get()); - tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 400)}); + + tabs.push_back(Tab{create_body(), std::make_unique<BookmarksPage>(this, search_page.get()), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)}); auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA); tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + + start_tab_index = 1; } else if(strcmp(plugin_name, "onimanga") == 0) { auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "https://onimanga.com/"); add_onimanga_handlers(search_page.get()); + + tabs.push_back(Tab{create_body(), std::make_unique<BookmarksPage>(this, search_page.get()), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)}); auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA); tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + + start_tab_index = 1; } else if(strcmp(plugin_name, "manga") == 0) { auto mangadex = std::make_unique<MangadexSearchPage>(this); upgrade_legacy_mangadex_ids(this, mangadex.get()); @@ -1349,35 +1380,9 @@ namespace QuickMedia { LOGIN }; - // Returns relative time as a string (approximation) - static std::string seconds_to_relative_time_str(time_t seconds) { - seconds = std::max(0L, seconds); - - time_t minutes = seconds / 60; - time_t hours = minutes / 60; - time_t days = hours / 24; - time_t months = days / 30; - time_t years = days / 365; - - if(years >= 1) - return std::to_string(years) + " year" + (years == 1 ? "" : "s") + " ago"; - else if(months >= 1) - return std::to_string(months) + " month" + (months == 1 ? "" : "s") + " ago"; - else if(days >= 1) - return std::to_string(days) + " day" + (days == 1 ? "" : "s") + " ago"; - else if(hours >= 1) - return std::to_string(hours) + " hour" + (hours == 1 ? "" : "s") + " ago"; - else if(minutes >= 1) - return std::to_string(minutes) + " minute" + (minutes == 1 ? "" : "s") + " ago"; - else - return std::to_string(seconds) + " second" + (seconds == 1 ? "" : "s") + " ago"; - } - static void fill_history_items_from_json(const Json::Value &history_json, BodyItems &history_items) { assert(history_json.isArray()); - BodyItems body_items; - time_t time_now = time(NULL); for(const Json::Value &item : history_json) { if(!item.isObject()) @@ -1403,12 +1408,10 @@ namespace QuickMedia { body_item->set_description("Watched " + seconds_to_relative_time_str(time_now - timestamp.asInt64())); body_item->set_description_color(get_current_theme().faded_text_color); body_item->thumbnail_size = sf::Vector2i(192, 108); - body_items.push_back(std::move(body_item)); + history_items.push_back(std::move(body_item)); } - for(auto it = body_items.rbegin(), end = body_items.rend(); it != end; ++it) { - history_items.push_back(std::move(*it)); - } + std::reverse(history_items.begin(), history_items.end()); } static Path get_video_history_filepath(const char *plugin_name) { @@ -1626,6 +1629,81 @@ namespace QuickMedia { return true; } + // Returns -1 if not found + int bookmark_find_item(Json::Value &root, const std::string &title, const std::string &author, const std::string &url) { + if(!root.isArray()) + return false; + + int index = -1; + for(const Json::Value &item_json : root) { + ++index; + if(!item_json.isObject()) + continue; + + const Json::Value &title_json = item_json["title"]; + const Json::Value &author_json = item_json["author"]; + const Json::Value &url_json = item_json["url"]; + if((!title.empty() && title_json.isString() && strcmp(title.c_str(), title_json.asCString()) == 0) + || (!author.empty() && author_json.isString() && strcmp(author.c_str(), author_json.asCString()) == 0) + || (!url.empty() && url_json.isString() && strcmp(url.c_str(), url_json.asCString()) == 0)) + { + return index; + } + } + + return -1; + } + + bool Program::toggle_bookmark(BodyItem *body_item, const char *bookmark_name) { + assert(bookmark_name); + Path bookmark_path = get_storage_dir().join("bookmarks"); + if(create_directory_recursive(bookmark_path) != 0) { + show_notification("QuickMedia", "Failed to update bookmark", Urgency::CRITICAL); + return false; + } + + bookmark_path.join(bookmark_name); + Json::Value json_root; + if(!read_file_as_json(bookmark_path, json_root) || !json_root.isArray()) + json_root = Json::Value(Json::arrayValue); + + const int existing_index = bookmark_find_item(json_root, body_item->get_title(), body_item->get_author(), body_item->url); + if(existing_index != -1) { + Json::Value removed; + json_root.removeIndex(existing_index, &removed); + if(!save_json_to_file_atomic(bookmark_path, json_root)) { + show_notification("QuickMedia", "Failed to update bookmark", Urgency::CRITICAL); + return false; + } + + std::string bookmark_title = body_item->get_title(); + if(bookmark_title.empty()) bookmark_title = body_item->get_author(); + show_notification("QuickMedia", "Removed " + bookmark_title + " from bookmarks"); + removed = true; + return true; + } + + Json::Value new_item(Json::objectValue); + if(!body_item->get_title().empty()) + new_item["title"] = body_item->get_title(); + if(!body_item->get_author().empty()) + new_item["author"] = body_item->get_author(); + if(!body_item->url.empty()) + new_item["url"] = body_item->url; + new_item["timestamp"] = (int64_t)time(nullptr); + + json_root.append(std::move(new_item)); + if(!save_json_to_file_atomic(bookmark_path, json_root)) { + show_notification("QuickMedia", "Failed to update bookmark", Urgency::CRITICAL); + return false; + } + + std::string bookmark_title = body_item->get_title(); + if(bookmark_title.empty()) bookmark_title = body_item->get_author(); + show_notification("QuickMedia", "Added " + bookmark_title + " to bookmarks"); + return true; + } + void Program::page_loop_render(sf::RenderWindow &window, std::vector<Tab> &tabs, int selected_tab, TabAssociatedData &tab_associated_data, const Json::Value *json_chapters, Tabs &ui_tabs) { if(tabs[selected_tab].search_bar) tabs[selected_tab].search_bar->draw(window, window_size, true); @@ -2053,6 +2131,19 @@ namespace QuickMedia { return trackable_page->track(selected_item->get_title()) == TrackResult::OK; }); } + } else if(event.key.code == sf::Keyboard::B && event.key.control) { + BodyItem *selected_item = tabs[selected_tab].body->get_selected(); + if(selected_item) { + const char *bookmark_name = tabs[selected_tab].page->get_bookmark_name(); + if(bookmark_name) { + if(toggle_bookmark(selected_item, bookmark_name)) { + for(Tab &tab : tabs) { + if(tab.page && tab.page->is_bookmark_page()) + tab.page->needs_refresh = true; + } + } + } + } } else if(event.key.code == sf::Keyboard::C && event.key.control) { BodyItem *selected_item = tabs[selected_tab].body->get_selected(); if(selected_item) { @@ -7422,7 +7513,7 @@ namespace QuickMedia { redraw = true; } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Tab) { file_name_entry.set_editable(!file_name_entry.is_editable()); - search_bar->set_editable(!file_name_entry.is_editable()); + search_bar->set_editable(!search_bar->is_editable()); } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Enter && event.key.control) { std::string save_path = save_file(); if(!save_path.empty()) |