aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-03-01 15:13:35 +0100
committerdec05eba <dec05eba@protonmail.com>2022-03-01 15:13:35 +0100
commit3ac82fad6bc883d979090e8cd56f3611703d6e14 (patch)
tree5960826029f56101065fac99e3bc3a1665a50ca7 /src
parent29d3f495e3b3be801cbb8c8dbd3f7250ec22415a (diff)
Make login a bit generalized, readd 4chan login (not tested)
Diffstat (limited to 'src')
-rw-r--r--src/QuickMedia.cpp227
-rw-r--r--src/plugins/Fourchan.cpp159
-rw-r--r--src/plugins/ImageBoard.cpp7
-rw-r--r--src/plugins/Page.cpp9
4 files changed, 253 insertions, 149 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 15a7f50..d49aa32 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -1176,11 +1176,20 @@ namespace QuickMedia {
tabs.push_back(Tab{std::move(categories_sukebei_body), std::make_unique<NyaaSiCategoryPage>(this, true), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "4chan") == 0) {
auto boards_page = std::make_unique<FourchanBoardsPage>(this, resources_root);
+ FourchanBoardsPage *boards_page_ptr = boards_page.get();
+
auto boards_body = create_body();
BodyItems body_items;
boards_page->get_boards(body_items);
boards_body->set_items(std::move(body_items));
tabs.push_back(Tab{std::move(boards_body), std::move(boards_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+
+ auto login_page = std::make_unique<FourchanLoginPage>(this, "4chan pass login", boards_page_ptr, &tabs, 1);
+ FourchanLoginPage *login_page_ptr = login_page.get();
+
+ tabs.push_back(Tab{ create_body(), std::move(login_page), nullptr, {} });
+ login_page_ptr->login_inputs = &tabs.back().login_inputs;
+ page_loop(tabs);
} else if(strcmp(plugin_name, "hotexamples") == 0) {
auto body = create_body();
BodyItems body_items;
@@ -1700,6 +1709,24 @@ namespace QuickMedia {
return search_bar;
}
+ void Program::add_login_inputs(Tab *tab, std::vector<LoginInput> login_inputs) {
+ if(login_inputs.empty())
+ return;
+
+ std::lock_guard<std::mutex> lock(login_inputs_mutex);
+ for(const LoginInput &login_input : login_inputs) {
+ auto search_bar = std::make_unique<SearchBar>(nullptr, &rounded_rectangle_shader, login_input.placeholder, login_input.type);
+ search_bar->padding_top = 0.0f;
+ search_bar->padding_bottom = 0.0f;
+ search_bar->padding_x = 0.0f;
+ search_bar->caret_visible = false;
+ tab->login_inputs.inputs.push_back(std::move(search_bar));
+ }
+
+ tab->login_inputs.inputs.front()->caret_visible = true;
+ tab->login_inputs.needs_refresh = true;
+ }
+
bool Program::load_manga_content_storage(const char *service_name, const std::string &manga_title, const std::string &manga_url, const std::string &manga_id) {
Path content_storage_dir = get_storage_dir().join(service_name);
this->manga_id = manga_id;
@@ -1996,7 +2023,7 @@ namespace QuickMedia {
const int selected_tab = ui_tabs.get_selected();
auto selected_item = tabs[selected_tab].body->get_selected_shared();
- if(!selected_item && search_text.empty())
+ if(!selected_item && search_text.empty() && !tabs[selected_tab].page->allow_submit_no_selection())
return;
if(tabs[selected_tab].page->allow_submit_no_selection() && (window.is_key_pressed(mgl::Keyboard::LControl) || window.is_key_pressed(mgl::Keyboard::RControl)))
@@ -2267,6 +2294,22 @@ namespace QuickMedia {
}
}
+ RoundedRectangle login_inputs_background(mgl::vec2f(1.0f, 1.0f), 10.0f * get_config().scale, get_theme().shade_color, &rounded_rectangle_shader);
+ for(auto &tab : tabs) {
+ for(auto &login_input : tab.login_inputs.inputs) {
+ login_input->padding_top = 0.0f;
+ login_input->padding_bottom = 0.0f;
+ login_input->padding_x = 0.0f;
+ login_input->caret_visible = false;
+ }
+
+ if(!tab.login_inputs.inputs.empty())
+ tab.login_inputs.inputs.front()->caret_visible = true;
+ }
+ const float login_input_padding_x = std::floor(20.0f * get_config().scale * get_config().spacing_scale);
+ const float login_input_padding_y = std::floor(20.0f * get_config().scale * get_config().spacing_scale);
+ const float login_input_spacing_y = std::floor(20.0f * get_config().scale * get_config().spacing_scale);
+
mgl::Event event;
mgl::Clock frame_timer;
@@ -2340,8 +2383,22 @@ namespace QuickMedia {
redraw = true;
} else if(event.key.code == mgl::Keyboard::Tab && !event.key.control) {
set_search_bar_to_body_item_text(tabs[selected_tab].body->get_selected(), tabs[selected_tab].search_bar.get());
+
+ std::lock_guard<std::mutex> lock(login_inputs_mutex);
+ if(!tabs[selected_tab].login_inputs.inputs.empty()) {
+ for(auto &login_input : tabs[selected_tab].login_inputs.inputs) {
+ login_input->caret_visible = false;
+ }
+ tabs[selected_tab].login_inputs.focused_input = (tabs[selected_tab].login_inputs.focused_input + 1) % tabs[selected_tab].login_inputs.inputs.size();
+ tabs[selected_tab].login_inputs.inputs[tabs[selected_tab].login_inputs.focused_input]->caret_visible = true;
+ idle_active_handler();
+ }
}
}
+
+ std::lock_guard<std::mutex> lock(login_inputs_mutex);
+ if(!tabs[selected_tab].login_inputs.inputs.empty())
+ tabs[selected_tab].login_inputs.inputs[tabs[selected_tab].login_inputs.focused_input]->on_event(window, event);
}
update_idle_state();
handle_x11_events();
@@ -2351,8 +2408,9 @@ namespace QuickMedia {
const int selected_tab = ui_tabs.get_selected();
- if(redraw) {
+ if(redraw || tabs[selected_tab].login_inputs.needs_refresh) {
redraw = false;
+ tabs[selected_tab].login_inputs.needs_refresh = false;
if(tabs[selected_tab].search_bar) tabs[selected_tab].search_bar->onWindowResize(window_size.to_vec2f());
// TODO: Dont show tabs if there is only one tab
get_body_dimensions(window_size, tabs[selected_tab].search_bar.get(), body_pos, body_size, true);
@@ -2382,6 +2440,20 @@ namespace QuickMedia {
gradient_points[3].position.x = 0.0f;
gradient_points[3].position.y = body_pos.y + gradient_height;
}
+
+ std::lock_guard<std::mutex> lock(login_inputs_mutex);
+ const int num_inputs = tabs[selected_tab].login_inputs.inputs.size();
+ const int first_input_height = tabs[selected_tab].login_inputs.inputs.empty() ? 0 : tabs[selected_tab].login_inputs.inputs.front()->getBottomWithoutShadow();
+ login_inputs_background.set_size(mgl::vec2f(
+ std::min((float)window_size.x, std::max(640.0f, window_size.x * 0.5f)),
+ num_inputs * first_input_height + login_input_padding_y * 2.0f + login_input_spacing_y * std::max(0, num_inputs - 1)));
+ login_inputs_background.set_position(window_size.to_vec2f() * 0.5f - login_inputs_background.get_size() * 0.5f);
+
+ mgl::vec2f pos = login_inputs_background.get_position() + mgl::vec2f(login_input_padding_x, login_input_padding_y);
+ for(auto &login_input : tabs[selected_tab].login_inputs.inputs) {
+ login_input->set_position(pos);
+ pos.y += login_input->getBottomWithoutShadow() + login_input_spacing_y;
+ }
}
if(tab_associated_data[selected_tab].fetching_next_page_running) {
@@ -2573,6 +2645,17 @@ namespace QuickMedia {
window.clear(get_theme().background_color);
page_loop_render(window, tabs, selected_tab, tab_associated_data[selected_tab], json_chapters, ui_tabs);
+ {
+ std::lock_guard<std::mutex> lock(login_inputs_mutex);
+ if(!tabs[selected_tab].login_inputs.inputs.empty()) {
+ login_inputs_background.draw(window);
+ for(auto &login_input : tabs[selected_tab].login_inputs.inputs) {
+ login_input->update();
+ login_input->draw(window, login_inputs_background.get_size() - mgl::vec2f(login_input_padding_x * 2.0f, 0.0f), false);
+ }
+ }
+ }
+
if(tabs[selected_tab].body->get_num_items() > 0) {
if(tabs[selected_tab].body->attach_side == AttachSide::TOP && !tabs[selected_tab].body->is_bottom_cut_off())
on_reached_end();
@@ -4817,116 +4900,62 @@ namespace QuickMedia {
}
}
- void Program::chat_login_page() {
- assert(strcmp(plugin_name, "matrix") == 0);
-
- SearchBar login_input(nullptr, &rounded_rectangle_shader, "Username", SearchBarType::Text);
- SearchBar password_input(nullptr, &rounded_rectangle_shader, "Password", SearchBarType::Password);
- SearchBar homeserver_input(nullptr, &rounded_rectangle_shader, "Homeserver", SearchBarType::Text);
-
- const int num_inputs = 3;
- SearchBar *inputs[num_inputs] = { &login_input, &password_input, &homeserver_input };
- int focused_input = 0;
-
- RoundedRectangle background(mgl::vec2f(1.0f, 1.0f), 10.0f * get_config().scale, get_theme().shade_color, &rounded_rectangle_shader);
+ class MatrixLoginPage : public LoginPage {
+ public:
+ MatrixLoginPage(Program *program, std::string title, Matrix *matrix) :
+ LoginPage(program), title(std::move(title)), matrix(matrix) {}
+ const char* get_title() const override { return title.c_str(); }
- auto text_submit_callback = [this, inputs](const std::string&) {
- for(int i = 0; i < num_inputs; ++i) {
- if(inputs[i]->get_text().empty()) {
+ PluginResult submit(const SubmitArgs&, std::vector<Tab>&) override {
+ for(const auto &login_input : login_inputs->inputs) {
+ if(login_input->get_text().empty()) {
show_notification("QuickMedia", "All fields need to be filled in", Urgency::CRITICAL);
- return;
+ return PluginResult::OK;
}
}
- run_task_with_loading_screen([this, inputs](){
- std::string homeserver = inputs[2]->get_text();
- if(!string_starts_with(homeserver, "http://") && !string_starts_with(homeserver, "https://"))
- homeserver = "https://" + homeserver;
+ std::string homeserver = login_inputs->inputs[2]->get_text();
+ if(!string_starts_with(homeserver, "http://") && !string_starts_with(homeserver, "https://"))
+ homeserver = "https://" + homeserver;
- std::string err_msg;
- if(matrix->login(inputs[0]->get_text(), inputs[1]->get_text(), homeserver, err_msg) == PluginResult::OK) {
- current_page = PageType::CHAT;
- return true;
- } else {
- // TODO: Do a proper check for this
- if(err_msg.find("Failed to parse") != std::string::npos)
- show_notification("QuickMedia", "Failed to login, error: " + err_msg + ". Did you perhaps specify an invalid homeserver?", Urgency::CRITICAL);
- else
- show_notification("QuickMedia", "Failed to login, error: " + err_msg, Urgency::CRITICAL);
- return false;
- }
- });
- };
-
- for(int i = 0; i < num_inputs; ++i) {
- inputs[i]->padding_top = 0.0f;
- inputs[i]->padding_bottom = 0.0f;
- inputs[i]->padding_x = 0.0f;
- inputs[i]->caret_visible = false;
- inputs[i]->onTextSubmitCallback = text_submit_callback;
+ std::string err_msg;
+ if(matrix->login(login_inputs->inputs[0]->get_text(), login_inputs->inputs[1]->get_text(), homeserver, err_msg) == PluginResult::OK) {
+ login_finish();
+ return PluginResult::OK;
+ } else {
+ // TODO: Do a proper check for this
+ if(err_msg.find("Failed to parse") != std::string::npos)
+ show_notification("QuickMedia", "Failed to login, error: " + err_msg + ". Did you perhaps specify an invalid homeserver?", Urgency::CRITICAL);
+ else
+ show_notification("QuickMedia", "Failed to login, error: " + err_msg, Urgency::CRITICAL);
+ return PluginResult::OK;
+ }
}
- inputs[focused_input]->caret_visible = true;
- const float padding_x = std::floor(20.0f * get_config().scale * get_config().spacing_scale);
- const float padding_y = std::floor(20.0f * get_config().scale * get_config().spacing_scale);
- const float spacing_y = std::floor(20.0f * get_config().scale * get_config().spacing_scale);
- mgl::vec2f body_pos;
- mgl::vec2f body_size;
- bool redraw = true;
- mgl::Event event;
-
- while (current_page == PageType::CHAT_LOGIN && window.is_open()) {
- while (window.poll_event(event)) {
- common_event_handler(event);
- event_idle_handler(event);
+ const LoginInputs *login_inputs;
+ private:
+ std::string title;
+ Matrix *matrix;
+ };
- if(event.type == mgl::Event::Resized) {
- window_size.x = event.size.width;
- window_size.y = event.size.height;
- redraw = true;
- idle_active_handler();
- } else if(event.type == mgl::Event::GainedFocus) {
- redraw = true;
- } else if(event.type == mgl::Event::KeyPressed && event.key.code == mgl::Keyboard::Tab) {
- for(int i = 0; i < num_inputs; ++i) {
- inputs[i]->caret_visible = false;
- }
- focused_input = (focused_input + 1) % num_inputs;
- inputs[focused_input]->caret_visible = true;
- idle_active_handler();
- }
- inputs[focused_input]->on_event(window, event);
- }
- update_idle_state();
- handle_x11_events();
+ void Program::chat_login_page() {
+ assert(strcmp(plugin_name, "matrix") == 0);
- if(current_page != PageType::CHAT_LOGIN)
- break;
+ LoginInputs login_inputs;
+ login_inputs.inputs.push_back(std::make_unique<SearchBar>(nullptr, &rounded_rectangle_shader, "Username", SearchBarType::Text));
+ login_inputs.inputs.push_back(std::make_unique<SearchBar>(nullptr, &rounded_rectangle_shader, "Password", SearchBarType::Password));
+ login_inputs.inputs.push_back(std::make_unique<SearchBar>(nullptr, &rounded_rectangle_shader, "Homeserver", SearchBarType::Text));
- if(redraw) {
- redraw = false;
- get_body_dimensions(window_size, nullptr, body_pos, body_size);
- background.set_size(mgl::vec2f(
- std::min((float)window_size.x, std::max(640.0f, window_size.x * 0.5f)),
- num_inputs * inputs[0]->getBottomWithoutShadow() + padding_y * 2.0f + spacing_y * std::max(0, num_inputs - 1)));
- background.set_position(window_size.to_vec2f() * 0.5f - background.get_size() * 0.5f);
+ auto login_page = std::make_unique<MatrixLoginPage>(this, "Matrix login", matrix);
+ MatrixLoginPage *login_page_ptr = login_page.get();
- mgl::vec2f pos = background.get_position() + mgl::vec2f(padding_x, padding_y);
- for(int i = 0; i < num_inputs; ++i) {
- inputs[i]->set_position(pos);
- pos.y += inputs[i]->getBottomWithoutShadow() + spacing_y;
- }
- }
+ std::vector<Tab> tabs;
+ tabs.push_back(Tab{ create_body(), std::move(login_page), nullptr, std::move(login_inputs) });
+ login_page_ptr->login_inputs = &tabs.back().login_inputs;
+ page_loop(tabs);
- window.clear(get_theme().background_color);
- background.draw(window);
- for(int i = 0; i < num_inputs; ++i) {
- inputs[i]->update();
- inputs[i]->draw(window, background.get_size() - mgl::vec2f(padding_x * 2.0f, 0.0f), false);
- }
- AsyncImageLoader::get_instance().update();
- window.display();
- }
+ if(login_page_ptr->logged_in())
+ current_page = PageType::CHAT;
}
struct ChatTab {
diff --git a/src/plugins/Fourchan.cpp b/src/plugins/Fourchan.cpp
index d3d5a5c..51a3cc5 100644
--- a/src/plugins/Fourchan.cpp
+++ b/src/plugins/Fourchan.cpp
@@ -5,6 +5,7 @@
#include "../../include/NetUtils.hpp"
#include "../../include/Notification.hpp"
#include "../../external/cppcodec/base64_rfc4648.hpp"
+#include "../../include/QuickMedia.hpp"
#include <HtmlParser.h>
#include <json/reader.h>
#include <string.h>
@@ -35,6 +36,69 @@ namespace QuickMedia {
return strip(file_content.substr(pass_id_index, line_end - pass_id_index));
}
+ static bool is_logged_in() {
+ Path cookies_filepath;
+ if(get_cookies_filepath(cookies_filepath, SERVICE_NAME) != 0) {
+ fprintf(stderr, "Failed to get 4chan cookies filepath\n");
+ return false;
+ }
+
+ std::vector<CommandArg> additional_args = {
+ CommandArg{"-c", cookies_filepath.data},
+ CommandArg{"-b", cookies_filepath.data}
+ };
+
+ std::string website_data;
+ if(download_to_string("https://sys.4chan.org/auth", website_data, additional_args) != DownloadResult::OK) {
+ show_notification("QuickMedia", "Failed to check if you are logged in", Urgency::CRITICAL);
+ return false;
+ }
+
+ // TODO: Check if this is correct
+ return website_data.find("field-id") == std::string::npos;
+ }
+
+ static bool login(Page *page, const std::string &token, const std::string &pin, std::string &pass_id, std::string &response_msg) {
+ response_msg.clear();
+
+ Path cookies_filepath;
+ if(get_cookies_filepath(cookies_filepath, SERVICE_NAME) != 0) {
+ fprintf(stderr, "Failed to get 4chan cookies filepath\n");
+ return false;
+ }
+
+ std::vector<CommandArg> additional_args = {
+ CommandArg{"--form-string", "id=" + token},
+ CommandArg{"--form-string", "pin=" + pin},
+ CommandArg{"--form-string", "xhr=1"},
+ CommandArg{"-c", cookies_filepath.data}
+ };
+
+ Json::Value json_root;
+ DownloadResult result = page->download_json(json_root, "https://sys.4chan.org/auth", std::move(additional_args), true);
+ if(result != DownloadResult::OK) return false;
+
+ if(!json_root.isObject())
+ return false;
+
+ const Json::Value &status_json = json_root["status"];
+ if(!status_json.isNumeric())
+ return false;
+
+ const Json::Value &message_json = json_root["message"];
+ if(message_json.isString())
+ response_msg = message_json.asString();
+
+ if(status_json.asInt64() == 1) {
+ pass_id = get_pass_id_from_cookies_file(cookies_filepath);
+ if(pass_id.empty())
+ return false;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
struct CommentPiece {
enum class Type {
TEXT,
@@ -230,7 +294,7 @@ namespace QuickMedia {
}
PluginResult FourchanBoardsPage::submit(const SubmitArgs &args, std::vector<Tab> &result_tabs) {
- result_tabs.push_back(Tab{create_body(false, true), std::make_unique<FourchanThreadListPage>(program, args.title, args.url), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+ result_tabs.push_back(Tab{create_body(false, true), std::make_unique<FourchanThreadListPage>(program, args.title, args.url, pass_id), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
return PluginResult::OK;
}
@@ -271,6 +335,56 @@ namespace QuickMedia {
}
}
+ PluginResult FourchanLoginPage::submit(const SubmitArgs &args, std::vector<Tab>&) {
+ if(args.url == "logout") {
+ Path cookies_filepath;
+ if(get_cookies_filepath(cookies_filepath, SERVICE_NAME) == 0)
+ remove(cookies_filepath.data.c_str());
+
+ boards_page->pass_id.clear();
+ logged_in = LoggedIn::No;
+ needs_refresh = true;
+ return PluginResult::OK;
+ }
+
+ for(const auto &login_input : login_inputs->inputs) {
+ if(login_input->get_text().empty()) {
+ show_notification("QuickMedia", "All fields need to be filled in", Urgency::CRITICAL);
+ return PluginResult::OK;
+ }
+ }
+
+ std::string err_msg;
+ if(login(this, login_inputs->inputs[0]->get_text(), login_inputs->inputs[1]->get_text(), boards_page->pass_id, err_msg)) {
+ login_finish();
+ return PluginResult::OK;
+ } else {
+ show_notification("QuickMedia", "Failed to login, error: " + err_msg, Urgency::CRITICAL);
+ return PluginResult::OK;
+ }
+ }
+
+ PluginResult FourchanLoginPage::lazy_fetch(BodyItems &result_items) {
+ if(logged_in == LoggedIn::Yes || (logged_in == LoggedIn::Unknown && is_logged_in())) {
+ logged_in = LoggedIn::Yes;
+ auto logout_body_item = BodyItem::create("Logout");
+ logout_body_item->url = "logout";
+ result_items.push_back(std::move(logout_body_item));
+ } else {
+ logged_in = LoggedIn::No;
+ program->add_login_inputs(&tabs->at(tab_index), {
+ { "Token", SearchBarType::Text },
+ { "PIN", SearchBarType::Password }
+ });
+ }
+ return PluginResult::OK;
+ }
+
+ void FourchanLoginPage::login_finish() {
+ logged_in = LoggedIn::Yes;
+ needs_refresh = true;
+ }
+
// TODO: Merge with lazy fetch
PluginResult FourchanThreadListPage::submit(const SubmitArgs &args, std::vector<Tab> &result_tabs) {
Json::Value json_root;
@@ -366,7 +480,7 @@ namespace QuickMedia {
auto body = create_body(false);
body->set_items(std::move(result_items));
- result_tabs.push_back(Tab{std::move(body), std::make_unique<FourchanThreadPage>(program, board_id, args.url), nullptr});
+ result_tabs.push_back(Tab{std::move(body), std::make_unique<FourchanThreadPage>(program, board_id, args.url, pass_id), nullptr});
return PluginResult::OK;
}
@@ -454,47 +568,6 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult FourchanThreadPage::login(const std::string &token, const std::string &pin, std::string &response_msg) {
- response_msg.clear();
-
- Path cookies_filepath;
- if(get_cookies_filepath(cookies_filepath, SERVICE_NAME) != 0) {
- fprintf(stderr, "Failed to get 4chan cookies filepath\n");
- return PluginResult::ERR;
- }
-
- std::vector<CommandArg> additional_args = {
- CommandArg{"--form-string", "id=" + token},
- CommandArg{"--form-string", "pin=" + pin},
- CommandArg{"--form-string", "xhr=1"},
- CommandArg{"-c", cookies_filepath.data}
- };
-
- Json::Value json_root;
- DownloadResult result = download_json(json_root, "https://sys.4chan.org/auth", std::move(additional_args), true);
- if(result != DownloadResult::OK) return download_result_to_plugin_result(result);
-
- if(!json_root.isObject())
- return PluginResult::ERR;
-
- const Json::Value &status_json = json_root["status"];
- if(!status_json.isNumeric())
- return PluginResult::ERR;
-
- const Json::Value &message_json = json_root["message"];
- if(message_json.isString())
- response_msg = message_json.asString();
-
- if(status_json.asInt64() == 1) {
- pass_id = get_pass_id_from_cookies_file(cookies_filepath);
- if(pass_id.empty())
- return PluginResult::ERR;
- return PluginResult::OK;
- } else {
- return PluginResult::ERR;
- }
- }
-
static std::string file_get_filename(const std::string &filepath) {
size_t index = filepath.rfind('/');
if(index == std::string::npos)
diff --git a/src/plugins/ImageBoard.cpp b/src/plugins/ImageBoard.cpp
index b027b9e..e1ee8fa 100644
--- a/src/plugins/ImageBoard.cpp
+++ b/src/plugins/ImageBoard.cpp
@@ -5,13 +5,6 @@ namespace QuickMedia {
set_clipboard(body_item->get_title());
}
- PluginResult ImageBoardThreadPage::login(const std::string &token, const std::string &pin, std::string &response_msg) {
- (void)token;
- (void)pin;
- response_msg = "Login is not supported on this image board";
- return PluginResult::ERR;
- }
-
const std::string& ImageBoardThreadPage::get_pass_id() {
static std::string empty_str;
return empty_str;
diff --git a/src/plugins/Page.cpp b/src/plugins/Page.cpp
index 654c983..f5867e3 100644
--- a/src/plugins/Page.cpp
+++ b/src/plugins/Page.cpp
@@ -137,4 +137,13 @@ namespace QuickMedia {
return PluginResult::OK;
}
+
+ void LoginPage::login_finish() {
+ login_finished = true;
+ program->set_go_to_previous_page();
+ }
+
+ bool LoginPage::logged_in() const {
+ return login_finished;
+ }
} \ No newline at end of file