From 3ac82fad6bc883d979090e8cd56f3611703d6e14 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 1 Mar 2022 15:13:35 +0100 Subject: Make login a bit generalized, readd 4chan login (not tested) --- src/QuickMedia.cpp | 227 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 128 insertions(+), 99 deletions(-) (limited to 'src/QuickMedia.cpp') 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(this, true), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); } else if(strcmp(plugin_name, "4chan") == 0) { auto boards_page = std::make_unique(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(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 login_inputs) { + if(login_inputs.empty()) + return; + + std::lock_guard lock(login_inputs_mutex); + for(const LoginInput &login_input : login_inputs) { + auto search_bar = std::make_unique(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 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 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 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 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&) 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(nullptr, &rounded_rectangle_shader, "Username", SearchBarType::Text)); + login_inputs.inputs.push_back(std::make_unique(nullptr, &rounded_rectangle_shader, "Password", SearchBarType::Password)); + login_inputs.inputs.push_back(std::make_unique(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(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 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 { -- cgit v1.2.3