Login in config wizard

This commit is contained in:
David Kocik 2024-06-20 16:25:32 +02:00 committed by Lukas Matena
parent fd205c937c
commit b60fb76a4b
15 changed files with 206 additions and 31 deletions

View File

@ -215,6 +215,8 @@ set(SLIC3R_GUI_SOURCES
GUI/ConfigWizard.cpp GUI/ConfigWizard.cpp
GUI/ConfigWizard.hpp GUI/ConfigWizard.hpp
GUI/ConfigWizard_private.hpp GUI/ConfigWizard_private.hpp
GUI/ConfigWizardWebViewPage.cpp
GUI/ConfigWizardWebViewPage.hpp
GUI/MsgDialog.cpp GUI/MsgDialog.cpp
GUI/MsgDialog.hpp GUI/MsgDialog.hpp
GUI/UpdateDialogs.cpp GUI/UpdateDialogs.cpp

View File

@ -10,6 +10,7 @@
// FIXME: extract absolute units -> em // FIXME: extract absolute units -> em
#include "ConfigWizard_private.hpp" #include "ConfigWizard_private.hpp"
#include "ConfigWizardWebViewPage.hpp"
#include <algorithm> #include <algorithm>
#include <numeric> #include <numeric>
@ -2586,6 +2587,7 @@ void ConfigWizard::priv::load_pages()
index->clear(); index->clear();
index->add_page(page_welcome); index->add_page(page_welcome);
index->add_page(page_login);
index->add_page(page_update_manager); index->add_page(page_update_manager);
if (is_config_from_archive) { if (is_config_from_archive) {
@ -2772,7 +2774,7 @@ void ConfigWizard::priv::load_vendors()
void ConfigWizard::priv::add_page(ConfigWizardPage *page) void ConfigWizard::priv::add_page(ConfigWizardPage *page)
{ {
const int proportion = (page->shortname == _L("Filaments")) || (page->shortname == _L("SLA Materials")) ? 1 : 0; const int proportion = (page->shortname == _L("Filaments")) || (page->shortname == _L("SLA Materials") || page->shortname == _L("Log in")) ? 1 : 0;
hscroll_sizer->Add(page, proportion, wxEXPAND); hscroll_sizer->Add(page, proportion, wxEXPAND);
all_pages.push_back(page); all_pages.push_back(page);
} }
@ -3981,6 +3983,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
wxGetApp().SetWindowVariantForButton(p->btn_cancel); wxGetApp().SetWindowVariantForButton(p->btn_cancel);
p->add_page(p->page_welcome = new PageWelcome(this)); p->add_page(p->page_welcome = new PageWelcome(this));
p->add_page(p->page_login = new ConfigWizardWebViewPage(this));
p->add_page(p->page_update_manager = new PageUpdateManager(this)); p->add_page(p->page_update_manager = new PageUpdateManager(this));
// other pages will be loaded later after confirm repositories selection // other pages will be loaded later after confirm repositories selection
@ -4132,6 +4135,13 @@ bool ConfigWizard::run(RunReason reason, StartPage start_page)
} }
} }
void ConfigWizard::update_login()
{
if(p->page_login) {
p->page_login->login_changed();
}
}
const wxString& ConfigWizard::name(const bool from_menu/* = false*/) const wxString& ConfigWizard::name(const bool from_menu/* = false*/)
{ {
// A different naming convention is used for the Wizard on Windows & GTK vs. OSX. // A different naming convention is used for the Wizard on Windows & GTK vs. OSX.

View File

@ -87,6 +87,7 @@ public:
// Run the Wizard. Return whether it was completed. // Run the Wizard. Return whether it was completed.
bool run(RunReason reason, StartPage start_page = SP_WELCOME); bool run(RunReason reason, StartPage start_page = SP_WELCOME);
void update_login();
static const wxString& name(const bool from_menu = false); static const wxString& name(const bool from_menu = false);
protected: protected:

View File

@ -0,0 +1,97 @@
#include "ConfigWizardWebViewPage.hpp"
#include "WebView.hpp"
#include "UserAccount.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "slic3r/GUI/I18N.hpp"
#include <wx/webview.h>
namespace Slic3r {
namespace GUI {
wxDEFINE_EVENT(EVT_LOGIN_VIA_WIZARD, Event<std::string>);
ConfigWizardWebViewPage::ConfigWizardWebViewPage(ConfigWizard *parent)
// TRN Config wizard page headline.
: ConfigWizardPage(parent, _L("Log into the Prusa Account"), _L("Log in"))
{
p_user_account = wxGetApp().plater()->get_user_account();
assert(p_user_account);
bool logged = p_user_account->is_logged();
// Create the webview
m_browser_sizer = new wxBoxSizer(wxHORIZONTAL);
m_browser = WebView::CreateWebView(this, p_user_account->get_login_redirect_url(), {});
if (!m_browser) {
// TRN Config wizard page with a log in page.
wxStaticText* fail_text = new wxStaticText(this, wxID_ANY, _L("Failed to load a web browser. Logging in is not possible in the moment."));
append(fail_text);
return;
}
if (logged) {
// TRN Config wizard page with a log in web.
m_text = new wxStaticText(this, wxID_ANY, format_wxstr("You are logged as %1%.", p_user_account->get_username()));
} else {
// TRN Config wizard page with a log in web.
m_text = new wxStaticText(this, wxID_ANY, _L("Please log into your Prusa Account. This step is not mandatory."));
}
append(m_text);
m_browser_sizer->Add(m_browser, 1, wxEXPAND);
append(m_browser_sizer, 1, wxEXPAND);
m_browser_sizer->Show(!logged);
// Connect the webview events
Bind(wxEVT_WEBVIEW_ERROR, &ConfigWizardWebViewPage::on_error, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_NAVIGATING, &ConfigWizardWebViewPage::on_navigation_request, this, m_browser->GetId());
}
void ConfigWizardWebViewPage::login_changed()
{
assert(p_user_account && m_browser_sizer && m_text);
bool logged = p_user_account->is_logged();
m_browser_sizer->Show(!logged);
if (logged) {
// TRN Config wizard page with a log in web.
m_text->SetLabel(format_wxstr("You are logged as %1%.", p_user_account->get_username()));
} else {
// TRN Config wizard page with a log in web.
m_text->SetLabel(_L("Please log into your Prusa Account. This step is not mandatory."));
}
}
void ConfigWizardWebViewPage::on_error(wxWebViewEvent &evt)
{
#define WX_ERROR_CASE(type) \
case type: \
category = #type; \
break;
wxString category;
switch (evt.GetInt())
{
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CONNECTION);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CERTIFICATE);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_AUTH);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_SECURITY);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_NOT_FOUND);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_REQUEST);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_USER_CANCELLED);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER);
}
BOOST_LOG_TRIVIAL(error) << "WebViewPanel error: " << category;
}
void ConfigWizardWebViewPage::on_navigation_request(wxWebViewEvent &evt)
{
wxString url = evt.GetURL();
if (url.starts_with(L"prusaslicer")) {
evt.Veto();
wxPostEvent(wxGetApp().plater(), Event<std::string>(EVT_LOGIN_VIA_WIZARD, into_u8(url)));
}
}
}} // namespace Slic3r::GUI

View File

@ -0,0 +1,63 @@
#ifndef slic3r_ConfigWizardWebViewPage_hpp_
#define slic3r_ConfigWizardWebViewPage_hpp_
#include "ConfigWizard_private.hpp"
#include "Event.hpp"
class wxWebView;
class wxWebViewEvent;
namespace Slic3r {
namespace GUI {
wxDECLARE_EVENT(EVT_LOGIN_VIA_WIZARD, Event<std::string>);
/*
struct ConfigWizardPage: wxPanel
{
ConfigWizard *parent;
const wxString shortname;
wxBoxSizer *content;
const unsigned indent;
ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname, unsigned indent = 0);
virtual ~ConfigWizardPage();
template<class T>
T* append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
{
content->Add(thing, proportion, flag, border);
return thing;
}
wxStaticText* append_text(wxString text);
void append_spacer(int space);
ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
virtual void apply_custom_config(DynamicPrintConfig &config) {}
virtual void set_run_reason(ConfigWizard::RunReason run_reason) {}
virtual void on_activate() {}
};
*/
class UserAccount;
class ConfigWizardWebViewPage : public ConfigWizardPage
{
public:
ConfigWizardWebViewPage( ConfigWizard *parent);
virtual ~ConfigWizardWebViewPage() {}
void on_error(wxWebViewEvent &evt);
void on_navigation_request(wxWebViewEvent &evt);
void login_changed();
private:
wxWebView *m_browser{nullptr};
UserAccount *p_user_account{nullptr};
wxBoxSizer *m_browser_sizer{nullptr};
wxStaticText *m_text{nullptr};
};
}} // namespace Slic3r::GUI
#endif

View File

@ -98,6 +98,7 @@ struct BundleMap : std::map<std::string /* = vendor ID */, Bundle>
struct Materials; struct Materials;
class RepositoryUpdateUIManager; class RepositoryUpdateUIManager;
class ConfigWizardWebViewPage;
struct PrinterPickerEvent; struct PrinterPickerEvent;
@ -631,6 +632,7 @@ struct ConfigWizard::priv
wxButton *btn_cancel = nullptr; wxButton *btn_cancel = nullptr;
PageWelcome *page_welcome = nullptr; PageWelcome *page_welcome = nullptr;
ConfigWizardWebViewPage *page_login = nullptr;
PageUpdateManager*page_update_manager = nullptr; PageUpdateManager*page_update_manager = nullptr;
PageMaterials *page_filaments = nullptr; PageMaterials *page_filaments = nullptr;
PageMaterials *page_sla_materials = nullptr; PageMaterials *page_sla_materials = nullptr;

View File

@ -3286,18 +3286,19 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage
preset_updater->config_update(app_config->orig_version(), PresetUpdater::UpdateParams::SHOW_TEXT_BOX, repos); preset_updater->config_update(app_config->orig_version(), PresetUpdater::UpdateParams::SHOW_TEXT_BOX, repos);
} }
auto wizard = new ConfigWizard(mainframe); m_config_wizard = new ConfigWizard(mainframe);
cw_loading_dlg->Close(); cw_loading_dlg->Close();
const bool res = wizard->run(reason, start_page); const bool res = m_config_wizard->run(reason, start_page);
// !!! Deallocate memory after close ConfigWizard. // !!! Deallocate memory after close ConfigWizard.
// Note, that mainframe is a parent of ConfigWizard. // Note, that mainframe is a parent of ConfigWizard.
// So, wizard will be destroyed only during destroying of mainframe // So, wizard will be destroyed only during destroying of mainframe
// To avoid this state the wizard have to be disconnected from mainframe and Destroyed explicitly // To avoid this state the wizard have to be disconnected from mainframe and Destroyed explicitly
mainframe->RemoveChild(wizard); mainframe->RemoveChild(m_config_wizard);
wizard->Destroy(); m_config_wizard->Destroy();
m_config_wizard = nullptr;
if (res) { if (res) {
load_current_presets(); load_current_presets();
@ -3309,15 +3310,13 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage
return res; return res;
} }
#if 0 void GUI_App::update_wizard_login_page()
void GUI_App::update_login_dialog()
{ {
if (!m_login_dialog) { if (!m_config_wizard) {
return; return;
} }
m_login_dialog->update_account(); m_config_wizard->update_login();
} }
#endif // 0
void GUI_App::show_desktop_integration_dialog() void GUI_App::show_desktop_integration_dialog()
{ {

View File

@ -59,7 +59,6 @@ class NotificationManager;
class Downloader; class Downloader;
struct GUI_InitParams; struct GUI_InitParams;
class GalleryDialog; class GalleryDialog;
class LoginDialog;
class PresetArchiveDatabase; class PresetArchiveDatabase;
enum FileType enum FileType
@ -371,9 +370,7 @@ public:
void open_web_page_localized(const std::string &http_address); void open_web_page_localized(const std::string &http_address);
bool may_switch_to_SLA_preset(const wxString& caption); bool may_switch_to_SLA_preset(const wxString& caption);
bool run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page = ConfigWizard::SP_WELCOME); bool run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page = ConfigWizard::SP_WELCOME);
#if 0 void update_wizard_login_page();
void update_login_dialog();
#endif // 0
void show_desktop_integration_dialog(); void show_desktop_integration_dialog();
void show_downloader_registration_dialog(); void show_downloader_registration_dialog();
@ -454,9 +451,9 @@ private:
// change to vector of items when adding more items that require update // change to vector of items when adding more items that require update
//wxMenuItem* m_login_config_menu_item { nullptr }; //wxMenuItem* m_login_config_menu_item { nullptr };
std::map< ConfigMenuIDs, wxMenuItem*> m_config_menu_updatable_items; std::map< ConfigMenuIDs, wxMenuItem*> m_config_menu_updatable_items;
#if 0
std::unique_ptr<LoginDialog> m_login_dialog; ConfigWizard* m_config_wizard {nullptr};
#endif // 0
}; };
DECLARE_APP(GUI_App) DECLARE_APP(GUI_App)

View File

@ -97,6 +97,7 @@
#include "Mouse3DController.hpp" #include "Mouse3DController.hpp"
#include "Tab.hpp" #include "Tab.hpp"
#include "Jobs/ArrangeJob2.hpp" #include "Jobs/ArrangeJob2.hpp"
#include "ConfigWizardWebViewPage.hpp"
#include "Jobs/RotoptimizeJob.hpp" #include "Jobs/RotoptimizeJob.hpp"
#include "Jobs/SLAImportJob.hpp" #include "Jobs/SLAImportJob.hpp"
@ -868,6 +869,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
BOOST_LOG_TRIVIAL(trace) << "Received login from other instance event."; BOOST_LOG_TRIVIAL(trace) << "Received login from other instance event.";
user_account->on_login_code_recieved(evt.data); user_account->on_login_code_recieved(evt.data);
}); });
this->q->Bind(EVT_LOGIN_VIA_WIZARD, [this](Event<std::string> &evt) {
BOOST_LOG_TRIVIAL(trace) << "Received login from wizard.";
user_account->on_login_code_recieved(evt.data);
});
this->q->Bind(EVT_OPEN_PRUSAAUTH, [this](OpenPrusaAuthEvent& evt) { this->q->Bind(EVT_OPEN_PRUSAAUTH, [this](OpenPrusaAuthEvent& evt) {
BOOST_LOG_TRIVIAL(info) << "open browser: " << evt.data; BOOST_LOG_TRIVIAL(info) << "open browser: " << evt.data;
// first register url to be sure to get the code back // first register url to be sure to get the code back
@ -897,9 +902,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
this->main_frame->refresh_account_menu(true); this->main_frame->refresh_account_menu(true);
// Update sidebar printer status // Update sidebar printer status
sidebar->update_printer_presets_combobox(); sidebar->update_printer_presets_combobox();
#if 0 wxGetApp().update_wizard_login_page();
wxGetApp().update_login_dialog();
#endif // 0
this->show_action_buttons(this->ready_to_slice); this->show_action_buttons(this->ready_to_slice);
LogoutWebViewDialog dlg(this->q); LogoutWebViewDialog dlg(this->q);
@ -919,9 +922,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
this->main_frame->add_connect_webview_tab(); this->main_frame->add_connect_webview_tab();
// Update User name in TopBar // Update User name in TopBar
this->main_frame->refresh_account_menu(); this->main_frame->refresh_account_menu();
#if 0 wxGetApp().update_wizard_login_page();
wxGetApp().update_login_dialog();
#endif // 0
this->show_action_buttons(this->ready_to_slice); this->show_action_buttons(this->ready_to_slice);
} else { } else {
@ -990,9 +991,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
fwrite(evt.data.c_str(), 1, evt.data.size(), file); fwrite(evt.data.c_str(), 1, evt.data.size(), file);
fclose(file); fclose(file);
this->main_frame->refresh_account_menu(true); this->main_frame->refresh_account_menu(true);
#if 0
wxGetApp().update_login_dialog();
#endif // 0
}); });
this->q->Bind(EVT_UA_PRUSACONNECT_PRINTER_DATA_SUCCESS, [this](UserAccountSuccessEvent& evt) { this->q->Bind(EVT_UA_PRUSACONNECT_PRINTER_DATA_SUCCESS, [this](UserAccountSuccessEvent& evt) {
this->user_account->set_current_printer_data(evt.data); this->user_account->set_current_printer_data(evt.data);

View File

@ -38,6 +38,7 @@ public:
bool is_logged(); bool is_logged();
void do_login(); void do_login();
void do_logout(); void do_logout();
wxString get_login_redirect_url() { return m_communication->get_login_redirect_url(); }
void set_remember_session(bool remember); void set_remember_session(bool remember);
void toggle_remember_session(); void toggle_remember_session();

View File

@ -257,8 +257,7 @@ void UserAccountCommunication::on_uuid_map_success()
} }
} }
void UserAccountCommunication::login_redirect() wxString UserAccountCommunication::get_login_redirect_url() {
{
const std::string AUTH_HOST = "https://account.prusa3d.com"; const std::string AUTH_HOST = "https://account.prusa3d.com";
const std::string CLIENT_ID = client_id(); const std::string CLIENT_ID = client_id();
const std::string REDIRECT_URI = "prusaslicer://login"; const std::string REDIRECT_URI = "prusaslicer://login";
@ -270,6 +269,11 @@ void UserAccountCommunication::login_redirect()
wxString url = GUI::format_wxstr(L"%1%/o/authorize/?client_id=%2%&response_type=code&code_challenge=%3%&code_challenge_method=S256&scope=basic_info&redirect_uri=%4%&choose_account=1", AUTH_HOST, CLIENT_ID, code_challenge, REDIRECT_URI); wxString url = GUI::format_wxstr(L"%1%/o/authorize/?client_id=%2%&response_type=code&code_challenge=%3%&code_challenge_method=S256&scope=basic_info&redirect_uri=%4%&choose_account=1", AUTH_HOST, CLIENT_ID, code_challenge, REDIRECT_URI);
return url;
}
void UserAccountCommunication::login_redirect()
{
wxString url = get_login_redirect_url();
wxQueueEvent(m_evt_handler,new OpenPrusaAuthEvent(GUI::EVT_OPEN_PRUSAAUTH, std::move(url))); wxQueueEvent(m_evt_handler,new OpenPrusaAuthEvent(GUI::EVT_OPEN_PRUSAAUTH, std::move(url)));
} }

View File

@ -42,6 +42,7 @@ public:
void do_login(); void do_login();
void do_logout(); void do_logout();
void do_clear(); void do_clear();
wxString get_login_redirect_url();
// Trigger function starts various remote operations // Trigger function starts various remote operations
void enqueue_connect_status_action(); void enqueue_connect_status_action();
void enqueue_connect_printer_models_action(); void enqueue_connect_printer_models_action();

View File

@ -7,7 +7,7 @@
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url, std::vector<std::string>& message_handlers) wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url, const std::vector<std::string>& message_handlers)
{ {
#if wxUSE_WEBVIEW_EDGE #if wxUSE_WEBVIEW_EDGE
bool backend_available = wxWebView::IsBackendAvailable(wxWebViewBackendEdge); bool backend_available = wxWebView::IsBackendAvailable(wxWebViewBackendEdge);

View File

@ -10,7 +10,7 @@ class wxString;
namespace WebView namespace WebView
{ {
wxWebView *CreateWebView(wxWindow *parent, const wxString& url, std::vector<std::string>& message_handlers); wxWebView *CreateWebView(wxWindow *parent, const wxString& url, const std::vector<std::string>& message_handlers);
}; };
#endif // !slic3r_GUI_WebView_hpp_ #endif // !slic3r_GUI_WebView_hpp_

View File

@ -1259,7 +1259,7 @@ LoginWebViewDialog::LoginWebViewDialog(wxWindow *parent, std::string &ret_val, c
: WebViewDialog(parent : WebViewDialog(parent
, url , url
, _L("Log in dialog") , _L("Log in dialog")
, wxSize(std::max(parent->GetClientSize().x / 2, 100 * wxGetApp().em_unit()), std::max(parent->GetClientSize().y / 4 * 3, 50 * wxGetApp().em_unit())) , wxSize(parent->GetClientSize().x / 3, parent->GetClientSize().y / 4 * 3)
, {}) , {})
, m_ret_val(ret_val) , m_ret_val(ret_val)
{ {