mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-17 06:35:57 +08:00
SPE-2535: Handling Printables events
Fix of loading url and deleting cookies Handling Printables events: download and slice Link from notification to Printables tab Webview download notification cleanup No reload button on loading screen
This commit is contained in:
parent
2d41c29505
commit
7ffa854ec2
@ -71,7 +71,7 @@
|
|||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<button style="margin-top: 20px; padding: 10px 20px; font-size: 16px;" onclick="window._prusaSlicer.postMessage(JSON.stringify({ action: 'RELOAD_HOME_PAGE' }))">Reload</button>
|
<!-- <button style="margin-top: 20px; padding: 10px 20px; font-size: 16px;" onclick="window._prusaSlicer.postMessage(JSON.stringify({ action: 'RELOAD_HOME_PAGE' }))">Reload</button> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<button style="margin-top: 20px; padding: 10px 20px; font-size: 16px;" onclick="window.ExternalApp.postMessage(JSON.stringify({ event: 'reloadHomePage' }))">Reload</button>
|
<!-- <button style="margin-top: 20px; padding: 10px 20px; font-size: 16px;" onclick="window.ExternalApp.postMessage(JSON.stringify({ event: 'reloadHomePage' }))">Reload</button> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -125,7 +125,7 @@ void ConfigWizardWebViewPage::on_navigation_request(wxWebViewEvent &evt)
|
|||||||
{
|
{
|
||||||
wxString url = evt.GetURL();
|
wxString url = evt.GetURL();
|
||||||
if (url.starts_with(L"prusaslicer")) {
|
if (url.starts_with(L"prusaslicer")) {
|
||||||
delete_cookies(m_browser, "https://account.prusa3d.com");
|
delete_cookies(m_browser, Utils::ServiceConfig::instance().account_url());
|
||||||
delete_cookies(m_browser, "https://accounts.google.com");
|
delete_cookies(m_browser, "https://accounts.google.com");
|
||||||
delete_cookies(m_browser, "https://appleid.apple.com");
|
delete_cookies(m_browser, "https://appleid.apple.com");
|
||||||
delete_cookies(m_browser, "https://facebook.com");
|
delete_cookies(m_browser, "https://facebook.com");
|
||||||
|
@ -90,14 +90,14 @@ std::string unescape_url(const std::string& unescaped)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Download::Download(int ID, std::string url, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder)
|
Download::Download(int ID, std::string url, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder, bool load_after)
|
||||||
: m_id(ID)
|
: m_id(ID)
|
||||||
, m_filename(filename_from_url(url))
|
, m_filename(filename_from_url(url))
|
||||||
, m_dest_folder(dest_folder)
|
, m_dest_folder(dest_folder)
|
||||||
{
|
{
|
||||||
assert(boost::filesystem::is_directory(dest_folder));
|
assert(boost::filesystem::is_directory(dest_folder));
|
||||||
m_final_path = dest_folder / m_filename;
|
m_final_path = dest_folder / m_filename;
|
||||||
m_file_get = std::make_shared<FileGet>(ID, std::move(url), m_filename, evt_handler, dest_folder);
|
m_file_get = std::make_shared<FileGet>(ID, std::move(url), m_filename, evt_handler, dest_folder, load_after);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Download::start()
|
void Download::start()
|
||||||
@ -132,11 +132,6 @@ void Download::resume()
|
|||||||
Downloader::Downloader()
|
Downloader::Downloader()
|
||||||
: wxEvtHandler()
|
: wxEvtHandler()
|
||||||
{
|
{
|
||||||
//Bind(EVT_DWNLDR_FILE_COMPLETE, [](const wxCommandEvent& evt) {});
|
|
||||||
//Bind(EVT_DWNLDR_FILE_PROGRESS, [](const wxCommandEvent& evt) {});
|
|
||||||
//Bind(EVT_DWNLDR_FILE_ERROR, [](const wxCommandEvent& evt) {});
|
|
||||||
//Bind(EVT_DWNLDR_FILE_NAME_CHANGE, [](const wxCommandEvent& evt) {});
|
|
||||||
|
|
||||||
Bind(EVT_DWNLDR_FILE_COMPLETE, &Downloader::on_complete, this);
|
Bind(EVT_DWNLDR_FILE_COMPLETE, &Downloader::on_complete, this);
|
||||||
Bind(EVT_DWNLDR_FILE_PROGRESS, &Downloader::on_progress, this);
|
Bind(EVT_DWNLDR_FILE_PROGRESS, &Downloader::on_progress, this);
|
||||||
Bind(EVT_DWNLDR_FILE_ERROR, &Downloader::on_error, this);
|
Bind(EVT_DWNLDR_FILE_ERROR, &Downloader::on_error, this);
|
||||||
@ -169,14 +164,38 @@ void Downloader::start_download(const std::string& full_url)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string text(escaped_url);
|
m_downloads.emplace_back(std::make_unique<Download>(id, std::move(escaped_url), this, m_dest_folder, true));
|
||||||
m_downloads.emplace_back(std::make_unique<Download>(id, std::move(escaped_url), this, m_dest_folder));
|
|
||||||
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
|
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
|
||||||
ntf_mngr->push_download_URL_progress_notification(id, m_downloads.back()->get_filename(), std::bind(&Downloader::user_action_callback, this, std::placeholders::_1, std::placeholders::_2));
|
ntf_mngr->push_download_URL_progress_notification(id, m_downloads.back()->get_filename(), std::bind(&Downloader::user_action_callback, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
m_downloads.back()->start();
|
m_downloads.back()->start();
|
||||||
BOOST_LOG_TRIVIAL(debug) << "started download";
|
BOOST_LOG_TRIVIAL(debug) << "started download";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Downloader::start_download_printables(const std::string& url, bool load_after, const std::string& printables_url, GUI_App* app)
|
||||||
|
{
|
||||||
|
assert(m_initialized);
|
||||||
|
|
||||||
|
size_t id = get_next_id();
|
||||||
|
|
||||||
|
if (!boost::starts_with(url, "https://") || !FileGet::is_subdomain(url, "printables.com")) {
|
||||||
|
std::string msg = format(_L("Download won't start. Download URL doesn't point to https://printables.com : %1%"), url);
|
||||||
|
BOOST_LOG_TRIVIAL(error) << msg;
|
||||||
|
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
|
||||||
|
ntf_mngr->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::RegularNotificationLevel, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_downloads.emplace_back(std::make_unique<Download>(id, url, this, m_dest_folder, load_after));
|
||||||
|
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
|
||||||
|
ntf_mngr->push_download_URL_progress_notification_with_printables_link( id
|
||||||
|
, m_downloads.back()->get_filename()
|
||||||
|
, printables_url
|
||||||
|
, std::bind(&Downloader::user_action_callback, this, std::placeholders::_1, std::placeholders::_2)
|
||||||
|
, std::bind(&GUI_App::open_link_in_printables, app, std::placeholders::_1)
|
||||||
|
);
|
||||||
|
m_downloads.back()->start();
|
||||||
|
}
|
||||||
|
|
||||||
void Downloader::on_progress(wxCommandEvent& event)
|
void Downloader::on_progress(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
size_t id = event.GetInt();
|
size_t id = event.GetInt();
|
||||||
@ -195,13 +214,13 @@ void Downloader::on_error(wxCommandEvent& event)
|
|||||||
ntf_mngr->set_download_URL_error(id, into_u8(event.GetString()));
|
ntf_mngr->set_download_URL_error(id, into_u8(event.GetString()));
|
||||||
show_error(nullptr, format_wxstr(L"%1%\n%2%", _L("The download has failed") + ":", event.GetString()));
|
show_error(nullptr, format_wxstr(L"%1%\n%2%", _L("The download has failed") + ":", event.GetString()));
|
||||||
}
|
}
|
||||||
void Downloader::on_complete(wxCommandEvent& event)
|
void Downloader::on_complete(Event<DownloadEventData>& event)
|
||||||
{
|
{
|
||||||
// TODO: is this always true? :
|
|
||||||
// here we open the file itself, notification should get 1.f progress from on progress.
|
// here we open the file itself, notification should get 1.f progress from on progress.
|
||||||
set_download_state(event.GetInt(), DownloadState::DownloadDone);
|
set_download_state(event.data.id, DownloadState::DownloadDone);
|
||||||
wxArrayString paths;
|
wxArrayString paths;
|
||||||
paths.Add(event.GetString());
|
paths.Add(event.data.path);
|
||||||
|
if (event.data.load_after)
|
||||||
wxGetApp().plater()->load_files(paths);
|
wxGetApp().plater()->load_files(paths);
|
||||||
}
|
}
|
||||||
bool Downloader::user_action_callback(DownloaderUserAction action, int id)
|
bool Downloader::user_action_callback(DownloaderUserAction action, int id)
|
||||||
|
@ -13,6 +13,7 @@ namespace Slic3r {
|
|||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
class NotificationManager;
|
class NotificationManager;
|
||||||
|
class GUI_App;
|
||||||
|
|
||||||
enum DownloadState
|
enum DownloadState
|
||||||
{
|
{
|
||||||
@ -35,7 +36,7 @@ enum DownloaderUserAction
|
|||||||
|
|
||||||
class Download {
|
class Download {
|
||||||
public:
|
public:
|
||||||
Download(int ID, std::string url, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder);
|
Download(int ID, std::string url, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder, bool load_after);
|
||||||
void start();
|
void start();
|
||||||
void cancel();
|
void cancel();
|
||||||
void pause();
|
void pause();
|
||||||
@ -67,6 +68,8 @@ public:
|
|||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
void start_download(const std::string& full_url);
|
void start_download(const std::string& full_url);
|
||||||
|
|
||||||
|
void start_download_printables(const std::string& url, bool load_after, const std::string& printables_url, GUI_App* app);
|
||||||
// cancel = false -> just pause
|
// cancel = false -> just pause
|
||||||
bool user_action_callback(DownloaderUserAction action, int id);
|
bool user_action_callback(DownloaderUserAction action, int id);
|
||||||
private:
|
private:
|
||||||
@ -80,7 +83,7 @@ private:
|
|||||||
|
|
||||||
void on_progress(wxCommandEvent& event);
|
void on_progress(wxCommandEvent& event);
|
||||||
void on_error(wxCommandEvent& event);
|
void on_error(wxCommandEvent& event);
|
||||||
void on_complete(wxCommandEvent& event);
|
void on_complete(Event<DownloadEventData>& event);
|
||||||
void on_name_change(wxCommandEvent& event);
|
void on_name_change(wxCommandEvent& event);
|
||||||
void on_paused(wxCommandEvent& event);
|
void on_paused(wxCommandEvent& event);
|
||||||
void on_canceled(wxCommandEvent& event);
|
void on_canceled(wxCommandEvent& event);
|
||||||
|
@ -71,7 +71,7 @@ unsigned get_current_pid()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// int = DOWNLOAD ID; string = file path
|
// int = DOWNLOAD ID; string = file path
|
||||||
wxDEFINE_EVENT(EVT_DWNLDR_FILE_COMPLETE, wxCommandEvent);
|
wxDEFINE_EVENT(EVT_DWNLDR_FILE_COMPLETE, Event<DownloadEventData>);
|
||||||
// int = DOWNLOAD ID; string = error msg
|
// int = DOWNLOAD ID; string = error msg
|
||||||
wxDEFINE_EVENT(EVT_DWNLDR_FILE_ERROR, wxCommandEvent);
|
wxDEFINE_EVENT(EVT_DWNLDR_FILE_ERROR, wxCommandEvent);
|
||||||
// int = DOWNLOAD ID; string = progress percent
|
// int = DOWNLOAD ID; string = progress percent
|
||||||
@ -97,17 +97,19 @@ struct FileGet::priv
|
|||||||
std::atomic_bool m_stopped { false }; // either canceled or paused - download is not running
|
std::atomic_bool m_stopped { false }; // either canceled or paused - download is not running
|
||||||
size_t m_written { 0 };
|
size_t m_written { 0 };
|
||||||
size_t m_absolute_size { 0 };
|
size_t m_absolute_size { 0 };
|
||||||
priv(int ID, std::string&& url, const std::string& filename, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder);
|
bool m_load_after;
|
||||||
|
priv(int ID, std::string&& url, const std::string& filename, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder, bool load_after);
|
||||||
|
|
||||||
void get_perform();
|
void get_perform();
|
||||||
};
|
};
|
||||||
|
|
||||||
FileGet::priv::priv(int ID, std::string&& url, const std::string& filename, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder)
|
FileGet::priv::priv(int ID, std::string&& url, const std::string& filename, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder, bool load_after)
|
||||||
: m_id(ID)
|
: m_id(ID)
|
||||||
, m_url(std::move(url))
|
, m_url(std::move(url))
|
||||||
, m_filename(filename)
|
, m_filename(filename)
|
||||||
, m_evt_handler(evt_handler)
|
, m_evt_handler(evt_handler)
|
||||||
, m_dest_folder(dest_folder)
|
, m_dest_folder(dest_folder)
|
||||||
|
, m_load_after(load_after)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,23 +266,8 @@ void FileGet::priv::get_perform()
|
|||||||
m_evt_handler->QueueEvent(evt);
|
m_evt_handler->QueueEvent(evt);
|
||||||
})
|
})
|
||||||
.on_complete([&](std::string body, unsigned /* http_status */) {
|
.on_complete([&](std::string body, unsigned /* http_status */) {
|
||||||
|
|
||||||
// TODO: perform a body size check
|
|
||||||
//
|
|
||||||
//size_t body_size = body.size();
|
|
||||||
//if (body_size != expected_size) {
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
if (m_written < body.size())
|
|
||||||
{
|
|
||||||
// this code should never be entered. As there should be on_progress call after last bit downloaded.
|
|
||||||
std::string part_for_write = body.substr(m_written);
|
|
||||||
fwrite(part_for_write.c_str(), 1, part_for_write.size(), file);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
boost::filesystem::rename(m_tmp_path, dest_path);
|
boost::filesystem::rename(m_tmp_path, dest_path);
|
||||||
}
|
}
|
||||||
@ -294,18 +281,15 @@ void FileGet::priv::get_perform()
|
|||||||
m_evt_handler->QueueEvent(evt);
|
m_evt_handler->QueueEvent(evt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
DownloadEventData event_data = {m_id, dest_path.wstring(), m_load_after};
|
||||||
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_COMPLETE);
|
wxQueueEvent(m_evt_handler, new Event<DownloadEventData>(EVT_DWNLDR_FILE_COMPLETE, event_data));
|
||||||
evt->SetString(dest_path.wstring());
|
|
||||||
evt->SetInt(m_id);
|
|
||||||
m_evt_handler->QueueEvent(evt);
|
|
||||||
})
|
})
|
||||||
.perform_sync();
|
.perform_sync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileGet::FileGet(int ID, std::string url, const std::string& filename, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder)
|
FileGet::FileGet(int ID, std::string url, const std::string& filename, wxEvtHandler* evt_handler, const boost::filesystem::path& dest_folder, bool load_after)
|
||||||
: p(new priv(ID, std::move(url), filename, evt_handler, dest_folder))
|
: p(new priv(ID, std::move(url), filename, evt_handler, dest_folder, load_after))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FileGet::FileGet(FileGet&& other) : p(std::move(other.p)) {}
|
FileGet::FileGet(FileGet&& other) : p(std::move(other.p)) {}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#ifndef slic3r_DownloaderFileGet_hpp_
|
#ifndef slic3r_DownloaderFileGet_hpp_
|
||||||
#define slic3r_DownloaderFileGet_hpp_
|
#define slic3r_DownloaderFileGet_hpp_
|
||||||
|
|
||||||
|
#include "Event.hpp"
|
||||||
|
|
||||||
#include "../Utils/Http.hpp"
|
#include "../Utils/Http.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -19,7 +21,7 @@ class FileGet : public std::enable_shared_from_this<FileGet> {
|
|||||||
private:
|
private:
|
||||||
struct priv;
|
struct priv;
|
||||||
public:
|
public:
|
||||||
FileGet(int ID, std::string url, const std::string& filename, wxEvtHandler* evt_handler,const boost::filesystem::path& dest_folder);
|
FileGet(int ID, std::string url, const std::string& filename, wxEvtHandler* evt_handler,const boost::filesystem::path& dest_folder, bool load_after);
|
||||||
FileGet(FileGet&& other);
|
FileGet(FileGet&& other);
|
||||||
~FileGet();
|
~FileGet();
|
||||||
|
|
||||||
@ -31,8 +33,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::unique_ptr<priv> p;
|
std::unique_ptr<priv> p;
|
||||||
};
|
};
|
||||||
|
struct DownloadEventData
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
wxString path;
|
||||||
|
bool load_after;
|
||||||
|
};
|
||||||
// int = DOWNLOAD ID; string = file path
|
// int = DOWNLOAD ID; string = file path
|
||||||
wxDECLARE_EVENT(EVT_DWNLDR_FILE_COMPLETE, wxCommandEvent);
|
wxDECLARE_EVENT(EVT_DWNLDR_FILE_COMPLETE, Event<DownloadEventData>);
|
||||||
// int = DOWNLOAD ID; string = error msg
|
// int = DOWNLOAD ID; string = error msg
|
||||||
wxDECLARE_EVENT(EVT_DWNLDR_FILE_PROGRESS, wxCommandEvent);
|
wxDECLARE_EVENT(EVT_DWNLDR_FILE_PROGRESS, wxCommandEvent);
|
||||||
// int = DOWNLOAD ID; string = progress percent
|
// int = DOWNLOAD ID; string = progress percent
|
||||||
|
@ -4112,13 +4112,46 @@ void GUI_App::show_printer_webview_tab()
|
|||||||
mainframe->show_printer_webview_tab(preset_bundle->physical_printers.get_selected_printer_config());
|
mainframe->show_printer_webview_tab(preset_bundle->physical_printers.get_selected_printer_config());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI_App::printables_request(const std::string& url)
|
|
||||||
|
void GUI_App::printables_download_request(const std::string& download_url, const std::string& model_url)
|
||||||
|
{
|
||||||
|
//this->mainframe->select_tab(size_t(0));
|
||||||
|
|
||||||
|
//lets always init so if the download dest folder was changed, new dest is used
|
||||||
|
boost::filesystem::path dest_folder(app_config->get("url_downloader_dest"));
|
||||||
|
if (dest_folder.empty() || !boost::filesystem::is_directory(dest_folder)) {
|
||||||
|
std::string msg = _u8L("Could not start URL download. Destination folder is not set. Please choose destination folder in Configuration Wizard.");
|
||||||
|
BOOST_LOG_TRIVIAL(error) << msg;
|
||||||
|
show_error(nullptr, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_downloader->init(dest_folder);
|
||||||
|
m_downloader->start_download_printables(download_url, false, model_url, this);
|
||||||
|
}
|
||||||
|
void GUI_App::printables_slice_request(const std::string& download_url, const std::string& model_url)
|
||||||
{
|
{
|
||||||
this->mainframe->select_tab(size_t(0));
|
this->mainframe->select_tab(size_t(0));
|
||||||
start_download(url);
|
|
||||||
|
//lets always init so if the download dest folder was changed, new dest is used
|
||||||
|
boost::filesystem::path dest_folder(app_config->get("url_downloader_dest"));
|
||||||
|
if (dest_folder.empty() || !boost::filesystem::is_directory(dest_folder)) {
|
||||||
|
std::string msg = _u8L("Could not start URL download. Destination folder is not set. Please choose destination folder in Configuration Wizard.");
|
||||||
|
BOOST_LOG_TRIVIAL(error) << msg;
|
||||||
|
show_error(nullptr, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_downloader->init(dest_folder);
|
||||||
|
m_downloader->start_download_printables(download_url, true, model_url, this);
|
||||||
|
}
|
||||||
|
void GUI_App::printables_print_request(const std::string& download_url, const std::string& model_url)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUI_App::open_link_in_printables(const std::string& url)
|
||||||
|
{
|
||||||
|
mainframe->show_printables_tab(url);
|
||||||
|
}
|
||||||
|
|
||||||
bool LogGui::ignorred_message(const wxString& msg)
|
bool LogGui::ignorred_message(const wxString& msg)
|
||||||
{
|
{
|
||||||
|
@ -436,7 +436,10 @@ public:
|
|||||||
void request_project_download(std::string project_id) {}
|
void request_project_download(std::string project_id) {}
|
||||||
void request_open_project(std::string project_id) {}
|
void request_open_project(std::string project_id) {}
|
||||||
void request_remove_project(std::string project_id) {}
|
void request_remove_project(std::string project_id) {}
|
||||||
void printables_request(const std::string& url);
|
void printables_download_request(const std::string& download_url, const std::string& model_url);
|
||||||
|
void printables_slice_request(const std::string& download_url, const std::string& model_url);
|
||||||
|
void printables_print_request(const std::string& download_url, const std::string& model_url);
|
||||||
|
void open_link_in_printables(const std::string& url);
|
||||||
private:
|
private:
|
||||||
bool on_init_inner();
|
bool on_init_inner();
|
||||||
void init_app_config();
|
void init_app_config();
|
||||||
|
@ -875,7 +875,15 @@ void MainFrame::show_connect_tab(const wxString& url)
|
|||||||
m_connect_webview->set_load_default_url_on_next_error(true);
|
m_connect_webview->set_load_default_url_on_next_error(true);
|
||||||
m_connect_webview->load_url(url);
|
m_connect_webview->load_url(url);
|
||||||
}
|
}
|
||||||
|
void MainFrame::show_printables_tab(const std::string& url)
|
||||||
|
{
|
||||||
|
if (!m_printables_webview_added) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_tabpanel->SetSelection(m_tabpanel->FindPage(m_printables_webview));
|
||||||
|
m_printables_webview->set_load_default_url_on_next_error(true);
|
||||||
|
m_printables_webview->load_url_from_outside(url);
|
||||||
|
}
|
||||||
void MainFrame::add_printables_webview_tab()
|
void MainFrame::add_printables_webview_tab()
|
||||||
{
|
{
|
||||||
if (m_printables_webview_added) {
|
if (m_printables_webview_added) {
|
||||||
@ -886,8 +894,7 @@ void MainFrame::add_printables_webview_tab()
|
|||||||
wxWindow* page = m_printables_webview;
|
wxWindow* page = m_printables_webview;
|
||||||
const wxString text(L"Printables");
|
const wxString text(L"Printables");
|
||||||
const std::string bmp_name = "";
|
const std::string bmp_name = "";
|
||||||
bool bSelect = false;
|
m_tabpanel->InsertNewPage(n, page, text, bmp_name, false);
|
||||||
m_tabpanel->InsertNewPage(n, page, text, bmp_name, bSelect);
|
|
||||||
m_printables_webview->load_default_url_delayed();
|
m_printables_webview->load_default_url_delayed();
|
||||||
m_printables_webview_added = true;
|
m_printables_webview_added = true;
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,7 @@ public:
|
|||||||
void on_account_did_refresh(const std::string& token);
|
void on_account_did_refresh(const std::string& token);
|
||||||
void on_account_logout();
|
void on_account_logout();
|
||||||
void show_connect_tab(const wxString& url);
|
void show_connect_tab(const wxString& url);
|
||||||
|
void show_printables_tab(const std::string& url);
|
||||||
|
|
||||||
void add_printables_webview_tab();
|
void add_printables_webview_tab();
|
||||||
void remove_printables_webview_tab();
|
void remove_printables_webview_tab();
|
||||||
|
@ -936,9 +936,8 @@ void NotificationManager::ProgressBarNotification::render_text(const float win_s
|
|||||||
render_cancel_button(win_size_x, win_size_y, win_pos_x, win_pos_y);
|
render_cancel_button(win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
render_bar(win_size_x, win_size_y, win_pos_x, win_pos_y);
|
render_bar(win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::ProgressBarNotification::render_bar(const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
void NotificationManager::ProgressBarNotification::render_bar(const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||||
{
|
{
|
||||||
ImVec4 orange_color = ImVec4(.99f, .313f, .0f, 1.0f);
|
ImVec4 orange_color = ImVec4(.99f, .313f, .0f, 1.0f);
|
||||||
@ -1073,6 +1072,51 @@ void NotificationManager::ProgressBarWithCancelNotification::render_bar(const fl
|
|||||||
ImGuiPureWrap::text(text.c_str());
|
ImGuiPureWrap::text(text.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------URLDownloadWithPrintablesLinkNotification----------------
|
||||||
|
void NotificationManager::URLDownloadWithPrintablesLinkNotification::init()
|
||||||
|
{
|
||||||
|
PopNotification::init();
|
||||||
|
//m_lines_count++;
|
||||||
|
if (m_endlines.empty()) {
|
||||||
|
m_endlines.push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lines_count = 3;
|
||||||
|
m_multiline = true;
|
||||||
|
while (m_endlines.size() < 3)
|
||||||
|
m_endlines.push_back(m_endlines.back());
|
||||||
|
|
||||||
|
if(m_state == EState::Shown)
|
||||||
|
m_state = EState::NotFading;
|
||||||
|
}
|
||||||
|
bool NotificationManager::URLDownloadWithPrintablesLinkNotification::on_text_click()
|
||||||
|
{
|
||||||
|
m_hypertext_callback_override(m_hypertext);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void NotificationManager::URLDownloadWithPrintablesLinkNotification::render_text(const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||||
|
{
|
||||||
|
assert(m_multiline);
|
||||||
|
assert(m_text1.size() >= m_endlines[0] || m_text1.size() >= m_endlines[1]);
|
||||||
|
if(m_endlines[0] > m_text1.size() || m_endlines[1] > m_text1.size())
|
||||||
|
return;
|
||||||
|
// 1 lines text (what doesn't fit, wont show), 1 line hypertext, 1 line bar
|
||||||
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
|
ImGui::SetCursorPosY(m_line_height / 4);
|
||||||
|
ImGuiPureWrap::text(m_text1.substr(0, m_endlines[0]).c_str());
|
||||||
|
|
||||||
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
|
ImGui::SetCursorPosY(m_line_height + m_line_height / 4);
|
||||||
|
std::string line = _u8L("Open Printables project page");
|
||||||
|
//ImGuiPureWrap::text(line.c_str());
|
||||||
|
render_hypertext(m_left_indentation, m_line_height + m_line_height / 4, line);
|
||||||
|
|
||||||
|
if (m_has_cancel_button)
|
||||||
|
render_cancel_button(win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
|
render_bar(win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//------URLDownloadNotification----------------
|
//------URLDownloadNotification----------------
|
||||||
|
|
||||||
void NotificationManager::URLDownloadNotification::render_close_button(const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
void NotificationManager::URLDownloadNotification::render_close_button(const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||||
@ -2495,6 +2539,19 @@ void NotificationManager::push_download_URL_progress_notification(size_t id, con
|
|||||||
push_notification_data(std::make_unique<NotificationManager::URLDownloadNotification>(data, m_id_provider, m_evt_handler, id, user_action_callback), 0);
|
push_notification_data(std::make_unique<NotificationManager::URLDownloadNotification>(data, m_id_provider, m_evt_handler, id, user_action_callback), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotificationManager::push_download_URL_progress_notification_with_printables_link(size_t id, const std::string& text, const std::string& url, std::function<bool(DownloaderUserAction, int)> user_action_callback, std::function<void(std::string)> hypertext_callback)
|
||||||
|
{
|
||||||
|
// If already exists
|
||||||
|
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||||
|
if (notification->get_type() == NotificationType::URLDownload && dynamic_cast<URLDownloadNotification*>(notification.get())->get_download_id() == id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// push new one
|
||||||
|
NotificationData data{ NotificationType::URLDownload, NotificationLevel::ProgressBarNotificationLevel, 30, _u8L("Download") + ": " + text, url };
|
||||||
|
push_notification_data(std::make_unique<NotificationManager::URLDownloadWithPrintablesLinkNotification>(data, m_id_provider, m_evt_handler, id, user_action_callback, hypertext_callback), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void NotificationManager::set_download_URL_progress(size_t id, float percentage)
|
void NotificationManager::set_download_URL_progress(size_t id, float percentage)
|
||||||
{
|
{
|
||||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||||
|
@ -244,6 +244,7 @@ public:
|
|||||||
void set_download_progress_percentage(float percentage);
|
void set_download_progress_percentage(float percentage);
|
||||||
// Download URL progress notif
|
// Download URL progress notif
|
||||||
void push_download_URL_progress_notification(size_t id, const std::string& text, std::function<bool(DownloaderUserAction, int)> user_action_callback);
|
void push_download_URL_progress_notification(size_t id, const std::string& text, std::function<bool(DownloaderUserAction, int)> user_action_callback);
|
||||||
|
void push_download_URL_progress_notification_with_printables_link(size_t id, const std::string& text, const std::string& url, std::function<bool(DownloaderUserAction, int)> user_action_callback, std::function<void(std::string)> hypertext_callback);
|
||||||
void set_download_URL_progress(size_t id, float percentage);
|
void set_download_URL_progress(size_t id, float percentage);
|
||||||
void set_download_URL_paused(size_t id);
|
void set_download_URL_paused(size_t id);
|
||||||
void set_download_URL_canceled(size_t id);
|
void set_download_URL_canceled(size_t id);
|
||||||
@ -577,6 +578,22 @@ private:
|
|||||||
std::string m_error_message;
|
std::string m_error_message;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class URLDownloadWithPrintablesLinkNotification : public URLDownloadNotification
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
URLDownloadWithPrintablesLinkNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, size_t download_id, std::function<bool(DownloaderUserAction, int)> user_action_callback, std::function<void(std::string)> hypertext_callback)
|
||||||
|
: URLDownloadNotification(n, id_provider, evt_handler, download_id, user_action_callback)
|
||||||
|
, m_hypertext_callback_override(hypertext_callback)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
void render_text(const float win_size_x, const float win_size_y,
|
||||||
|
const float win_pos_x, const float win_pos_y) override;
|
||||||
|
void init() override;
|
||||||
|
bool on_text_click() override;
|
||||||
|
std::function<void(std::string)> m_hypertext_callback_override;
|
||||||
|
};
|
||||||
|
|
||||||
class PrintHostUploadNotification : public ProgressBarNotification
|
class PrintHostUploadNotification : public ProgressBarNotification
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -639,7 +639,7 @@ void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt)
|
|||||||
{
|
{
|
||||||
wxString url = evt.GetURL();
|
wxString url = evt.GetURL();
|
||||||
if (url.starts_with(L"prusaslicer")) {
|
if (url.starts_with(L"prusaslicer")) {
|
||||||
delete_cookies(m_browser, "https://account.prusa3d.com");
|
delete_cookies(m_browser, Utils::ServiceConfig::instance().account_url());
|
||||||
delete_cookies(m_browser, "https://accounts.google.com");
|
delete_cookies(m_browser, "https://accounts.google.com");
|
||||||
delete_cookies(m_browser, "https://appleid.apple.com");
|
delete_cookies(m_browser, "https://appleid.apple.com");
|
||||||
delete_cookies(m_browser, "https://facebook.com");
|
delete_cookies(m_browser, "https://facebook.com");
|
||||||
|
@ -190,8 +190,7 @@ void WebViewPanel::on_show(wxShowEvent& evt)
|
|||||||
m_shown = evt.IsShown();
|
m_shown = evt.IsShown();
|
||||||
if (evt.IsShown() && m_load_default_url) {
|
if (evt.IsShown() && m_load_default_url) {
|
||||||
m_load_default_url = false;
|
m_load_default_url = false;
|
||||||
//load_url(m_default_url);
|
load_url(m_default_url);
|
||||||
load_error_page();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,6 +238,8 @@ void WebViewPanel::on_back_button(wxCommandEvent& WXUNUSED(evt))
|
|||||||
{
|
{
|
||||||
if (!m_browser)
|
if (!m_browser)
|
||||||
return;
|
return;
|
||||||
|
if (!m_browser->CanGoBack())
|
||||||
|
return;
|
||||||
m_browser->GoBack();
|
m_browser->GoBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +250,8 @@ void WebViewPanel::on_forward_button(wxCommandEvent& WXUNUSED(evt))
|
|||||||
{
|
{
|
||||||
if (!m_browser)
|
if (!m_browser)
|
||||||
return;
|
return;
|
||||||
|
if (!m_browser->CanGoForward())
|
||||||
|
return;
|
||||||
m_browser->GoForward();
|
m_browser->GoForward();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,7 +472,7 @@ case type: \
|
|||||||
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER);
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(error) << this <<" WebViewPanel error: " << category;
|
BOOST_LOG_TRIVIAL(error) << this <<" WebViewPanel error: " << category << " url: " << evt.GetURL();
|
||||||
load_error_page();
|
load_error_page();
|
||||||
#ifdef DEBUG_URL_PANEL
|
#ifdef DEBUG_URL_PANEL
|
||||||
m_info->ShowMessage(wxString("An error occurred loading ") + evt.GetURL() + "\n" +
|
m_info->ShowMessage(wxString("An error occurred loading ") + evt.GetURL() + "\n" +
|
||||||
@ -857,9 +860,14 @@ PrintablesWebViewPanel::PrintablesWebViewPanel(wxWindow* parent)
|
|||||||
: WebViewPanel(parent, GUI::from_u8(Utils::ServiceConfig::instance().printables_url()), { "ExternalApp" }, "other_loading_reload", "other_connection_failed")
|
: WebViewPanel(parent, GUI::from_u8(Utils::ServiceConfig::instance().printables_url()), { "ExternalApp" }, "other_loading_reload", "other_connection_failed")
|
||||||
{
|
{
|
||||||
m_browser->Bind(wxEVT_WEBVIEW_LOADED, &PrintablesWebViewPanel::on_loaded, this);
|
m_browser->Bind(wxEVT_WEBVIEW_LOADED, &PrintablesWebViewPanel::on_loaded, this);
|
||||||
|
|
||||||
m_events["accessTokenExpired"] = std::bind(&PrintablesWebViewPanel::on_printables_event_access_token_expired, this, std::placeholders::_1);
|
m_events["accessTokenExpired"] = std::bind(&PrintablesWebViewPanel::on_printables_event_access_token_expired, this, std::placeholders::_1);
|
||||||
m_events["printGcode"] = std::bind(&PrintablesWebViewPanel::on_printables_event_print_gcode, this, std::placeholders::_1);
|
|
||||||
m_events["reloadHomePage"] = std::bind(&PrintablesWebViewPanel::on_reload_event, this, std::placeholders::_1);
|
m_events["reloadHomePage"] = std::bind(&PrintablesWebViewPanel::on_reload_event, this, std::placeholders::_1);
|
||||||
|
m_events["printGcode"] = std::bind(&PrintablesWebViewPanel::on_printables_event_print_gcode, this, std::placeholders::_1);
|
||||||
|
m_events["downloadFile"] = std::bind(&PrintablesWebViewPanel::on_printables_event_download_file, this, std::placeholders::_1);
|
||||||
|
m_events["sliceFile"] = std::bind(&PrintablesWebViewPanel::on_printables_event_slice_file, this, std::placeholders::_1);
|
||||||
|
m_events["requiredLogin"] = std::bind(&PrintablesWebViewPanel::on_printables_event_required_login, this, std::placeholders::_1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintablesWebViewPanel::handle_message(const std::string& message)
|
void PrintablesWebViewPanel::handle_message(const std::string& message)
|
||||||
@ -888,50 +896,16 @@ void PrintablesWebViewPanel::handle_message(const std::string& message)
|
|||||||
m_events[event_string](message);
|
m_events[event_string](message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void PrintablesWebViewPanel::on_printables_event_access_token_expired(const std::string& message_data)
|
|
||||||
{
|
|
||||||
// accessTokenExpired
|
|
||||||
// Printables pozaduje refresh access tokenu, muze byt volano nekolikrat.Nechme na Mobilni aplikaci at zaridi to ze zareaguje jen jednou
|
|
||||||
}
|
|
||||||
void PrintablesWebViewPanel::on_printables_event_print_gcode(const std::string& message_data)
|
|
||||||
{
|
|
||||||
// printGcode
|
|
||||||
// Uzivatel kliknul na tlacitko tisk u gcode. Dalsi posilane atributy jsou url, material, printer, nozzlediam
|
|
||||||
}
|
|
||||||
void PrintablesWebViewPanel::on_reload_event(const std::string& message_data)
|
|
||||||
{
|
|
||||||
load_default_url();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Eventy Slicer -> Printables
|
|
||||||
accessTokenWillChange
|
|
||||||
WebUI zavola event predtim nez udela refresh access tokenu proti Prusa Accountu na Printables to bude znamenat pozastaveni requestu Mobile app muze chtit udelat refresh i bez explicitni predchozi printables zadosti skrz accessTokenExpired event
|
|
||||||
accessTokenChange
|
|
||||||
window postMessage JSON stringify { event 'accessTokenChange' token 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC' }
|
|
||||||
volani po uspesne rotaci tokenu
|
|
||||||
historyBack
|
|
||||||
navigace zpet triggerovana z mobilni aplikace
|
|
||||||
historyForward
|
|
||||||
navigace vpred triggerovana z mobilni aplikace
|
|
||||||
*/
|
|
||||||
|
|
||||||
void PrintablesWebViewPanel::on_navigation_request(wxWebViewEvent &evt)
|
void PrintablesWebViewPanel::on_navigation_request(wxWebViewEvent &evt)
|
||||||
{
|
{
|
||||||
const wxString url = evt.GetURL();
|
const wxString url = evt.GetURL();
|
||||||
// download with url
|
|
||||||
if (url.StartsWith(L"prusaslicer")) {
|
|
||||||
evt.Veto();
|
|
||||||
wxGetApp().printables_request(into_u8(url));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (url.StartsWith(m_default_url)) {
|
if (url.StartsWith(m_default_url)) {
|
||||||
m_reached_default_url = true;
|
m_reached_default_url = true;
|
||||||
} else if (m_reached_default_url) {
|
} else if (m_reached_default_url) {
|
||||||
BOOST_LOG_TRIVIAL(info) << evt.GetURL() << " does not start with default url. Vetoing.";
|
BOOST_LOG_TRIVIAL(info) << evt.GetURL() << " does not start with default url. Vetoing.";
|
||||||
evt.Veto();
|
evt.Veto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintablesWebViewPanel::load_default_url()
|
void PrintablesWebViewPanel::load_default_url()
|
||||||
@ -1055,7 +1029,7 @@ void PrintablesWebViewPanel::logout()
|
|||||||
#endif //
|
#endif //
|
||||||
|
|
||||||
}
|
}
|
||||||
void PrintablesWebViewPanel::login(const std::string access_token)
|
void PrintablesWebViewPanel::login(const std::string& access_token)
|
||||||
{
|
{
|
||||||
if (!m_shown) {
|
if (!m_shown) {
|
||||||
return;
|
return;
|
||||||
@ -1076,7 +1050,7 @@ void PrintablesWebViewPanel::login(const std::string access_token)
|
|||||||
|
|
||||||
run_script("window.location.reload();");
|
run_script("window.location.reload();");
|
||||||
}
|
}
|
||||||
void PrintablesWebViewPanel::send_refreshed_token(const std::string access_token)
|
void PrintablesWebViewPanel::send_refreshed_token(const std::string& access_token)
|
||||||
{
|
{
|
||||||
if (m_load_default_url) {
|
if (m_load_default_url) {
|
||||||
return;
|
return;
|
||||||
@ -1097,6 +1071,11 @@ void PrintablesWebViewPanel::send_will_refresh()
|
|||||||
run_script(script);
|
run_script(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintablesWebViewPanel::load_url_from_outside(const std::string& url)
|
||||||
|
{
|
||||||
|
load_url(from_u8(Utils::ServiceConfig::instance().printables_url() + url));
|
||||||
|
}
|
||||||
|
|
||||||
void PrintablesWebViewPanel::on_script_message(wxWebViewEvent& evt)
|
void PrintablesWebViewPanel::on_script_message(wxWebViewEvent& evt)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(error) << "received message from Printables: " << evt.GetString();
|
BOOST_LOG_TRIVIAL(error) << "received message from Printables: " << evt.GetString();
|
||||||
@ -1111,4 +1090,157 @@ void PrintablesWebViewPanel::sys_color_changed()
|
|||||||
WebViewPanel::sys_color_changed();
|
WebViewPanel::sys_color_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintablesWebViewPanel::on_printables_event_access_token_expired(const std::string& message_data)
|
||||||
|
{
|
||||||
|
// accessTokenExpired
|
||||||
|
// Printables pozaduje refresh access tokenu, muze byt volano nekolikrat.Nechme na Mobilni aplikaci at zaridi to ze zareaguje jen jednou
|
||||||
|
|
||||||
|
// We do no react on this event now - Our Acount managment should know when to renew our tokens.
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintablesWebViewPanel::on_reload_event(const std::string& message_data)
|
||||||
|
{
|
||||||
|
// Event from our error / loading html pages
|
||||||
|
load_default_url();
|
||||||
|
}
|
||||||
|
void PrintablesWebViewPanel::on_printables_event_print_gcode(const std::string& message_data)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< " " << message_data;
|
||||||
|
}
|
||||||
|
void PrintablesWebViewPanel::on_printables_event_download_file(const std::string& message_data)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " " << message_data;
|
||||||
|
// { "event": "downloadFile", "url": "https://media.printables.com/somesecure.stl", "modelUrl": "https://www.printables.com/model/123" }
|
||||||
|
std::string download_url;
|
||||||
|
std::string model_url;
|
||||||
|
try {
|
||||||
|
std::stringstream ss(message_data);
|
||||||
|
pt::ptree ptree;
|
||||||
|
pt::read_json(ss, ptree);
|
||||||
|
if (const auto url = ptree.get_optional<std::string>("url"); url) {
|
||||||
|
download_url = *url;
|
||||||
|
}
|
||||||
|
if (const auto url = ptree.get_optional<std::string>("modelUrl"); url) {
|
||||||
|
model_url = *url;
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Could not parse printables message. " << e.what();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(!download_url.empty() && !model_url.empty());
|
||||||
|
boost::filesystem::path url_path(download_url);
|
||||||
|
show_download_notification(url_path.filename().string());
|
||||||
|
wxGetApp().printables_download_request(download_url, model_url);
|
||||||
|
}
|
||||||
|
void PrintablesWebViewPanel::on_printables_event_slice_file(const std::string& message_data)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " " << message_data;
|
||||||
|
// { "event": "sliceFile", "url": "https://media.printables.com/somesecure.zip", "modelUrl": "https://www.printables.com/model/123" }
|
||||||
|
std::string download_url;
|
||||||
|
std::string model_url;
|
||||||
|
try {
|
||||||
|
std::stringstream ss(message_data);
|
||||||
|
pt::ptree ptree;
|
||||||
|
pt::read_json(ss, ptree);
|
||||||
|
if (const auto url = ptree.get_optional<std::string>("url"); url) {
|
||||||
|
download_url = *url;
|
||||||
|
}
|
||||||
|
if (const auto url = ptree.get_optional<std::string>("modelUrl"); url) {
|
||||||
|
model_url = *url;
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Could not parse printables message. " << e.what();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(!download_url.empty() && !model_url.empty());
|
||||||
|
wxGetApp().printables_slice_request(download_url, model_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintablesWebViewPanel::on_printables_event_required_login(const std::string& message_data)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " " << message_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintablesWebViewPanel::show_download_notification(const std::string& filename)
|
||||||
|
{
|
||||||
|
std::string message = GUI::format(_u8L("Downloading %1%"),filename);
|
||||||
|
std::string script = GUI::format(R"(
|
||||||
|
// Inject custom CSS
|
||||||
|
var style = document.createElement('style');
|
||||||
|
style.innerHTML = `
|
||||||
|
body {
|
||||||
|
/* Add your body styles here */
|
||||||
|
}
|
||||||
|
.notification-popup {
|
||||||
|
position: fixed;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 10px;
|
||||||
|
background-color: #333333; /* Dark background */
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 6px; /* Slightly rounded corners */
|
||||||
|
color: #ffffff; /* White text */
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.3); /* Add a subtle shadow */
|
||||||
|
min-width: 350px; /* Ensure it has a minimum width */
|
||||||
|
min-height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-popup a:hover {
|
||||||
|
text-decoration: underline; /* Underline on hover */
|
||||||
|
}
|
||||||
|
.notification-popup .close-button {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #ffa500; /* Orange border for the button */
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
.notification-popup .close-button:hover {
|
||||||
|
background-color: #ffa500; /* Orange background on hover */
|
||||||
|
color: #333333; /* Dark color for the "X" on hover */
|
||||||
|
}
|
||||||
|
.notification-popup .close-button:before {
|
||||||
|
content: 'X';
|
||||||
|
color: #ffa500; /* Orange "X" */
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
|
||||||
|
// Define the notification functions
|
||||||
|
function appendNotification() {
|
||||||
|
const body = document.getElementsByTagName('body')[0];
|
||||||
|
const notifDiv = document.createElement('div');
|
||||||
|
notifDiv.innerHTML = `
|
||||||
|
<div>
|
||||||
|
<b>PrusaSlicer: </b>%1%
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
notifDiv.className = 'notification-popup';
|
||||||
|
notifDiv.id = 'slicer-notification';
|
||||||
|
body.appendChild(notifDiv);
|
||||||
|
|
||||||
|
window.setTimeout(removeNotification, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeNotification() {
|
||||||
|
const notifDiv = document.getElementById('slicer-notification');
|
||||||
|
if (notifDiv)
|
||||||
|
notifDiv.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
appendNotification();
|
||||||
|
)", message);
|
||||||
|
run_script(script);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace slic3r::GUI
|
} // namespace slic3r::GUI
|
@ -180,20 +180,36 @@ public:
|
|||||||
void sys_color_changed() override;
|
void sys_color_changed() override;
|
||||||
|
|
||||||
void logout();
|
void logout();
|
||||||
void login(const std::string access_token);
|
void login(const std::string& access_token);
|
||||||
void send_refreshed_token(const std::string access_token);
|
void send_refreshed_token(const std::string& access_token);
|
||||||
void send_will_refresh();
|
void send_will_refresh();
|
||||||
|
void load_url_from_outside(const std::string& url);
|
||||||
private:
|
private:
|
||||||
void handle_message(const std::string& message);
|
void handle_message(const std::string& message);
|
||||||
void on_printables_event_access_token_expired(const std::string& message_data);
|
void on_printables_event_access_token_expired(const std::string& message_data);
|
||||||
void on_printables_event_print_gcode(const std::string& message_data);
|
|
||||||
void on_reload_event(const std::string& message_data);
|
void on_reload_event(const std::string& message_data);
|
||||||
|
void on_printables_event_print_gcode(const std::string& message_data);
|
||||||
|
void on_printables_event_download_file(const std::string& message_data);
|
||||||
|
void on_printables_event_slice_file(const std::string& message_data);
|
||||||
|
void on_printables_event_required_login(const std::string& message_data);
|
||||||
void load_default_url() override;
|
void load_default_url() override;
|
||||||
std::string get_url_lang_theme(const wxString& url);
|
std::string get_url_lang_theme(const wxString& url);
|
||||||
|
void show_download_notification(const std::string& filename);
|
||||||
|
|
||||||
std::map<std::string, std::function<void(const std::string&)>> m_events;
|
std::map<std::string, std::function<void(const std::string&)>> m_events;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Eventy Slicer -> Printables
|
||||||
|
accessTokenWillChange
|
||||||
|
WebUI zavola event predtim nez udela refresh access tokenu proti Prusa Accountu na Printables to bude znamenat pozastaveni requestu Mobile app muze chtit udelat refresh i bez explicitni predchozi printables zadosti skrz accessTokenExpired event
|
||||||
|
accessTokenChange
|
||||||
|
window postMessage JSON stringify { event 'accessTokenChange' token 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC' }
|
||||||
|
volani po uspesne rotaci tokenu
|
||||||
|
historyBack
|
||||||
|
navigace zpet triggerovana z mobilni aplikace
|
||||||
|
historyForward
|
||||||
|
navigace vpred triggerovana z mobilni aplikace
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
} // namespace Slic3r::GUI
|
} // namespace Slic3r::GUI
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user