Merge pull request #145 from amnezia-vpn/feature/qt6-server-busy-notification

feature/qt6-server-busy-notification
This commit is contained in:
pokamest 2023-01-18 00:43:13 +00:00 committed by GitHub
commit 9d01a52a4a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 573 additions and 369 deletions

View file

@ -21,13 +21,13 @@ set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "Autogen")
find_package(Qt6 REQUIRED COMPONENTS find_package(Qt6 REQUIRED COMPONENTS
Widgets Core Gui Network Xml Widgets Core Gui Network Xml
RemoteObjects Quick Svg QuickControls2 RemoteObjects Quick Svg QuickControls2
Core5Compat Core5Compat Concurrent
) )
set(LIBS ${LIBS} set(LIBS ${LIBS}
Qt6::Widgets Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Core Qt6::Gui
Qt6::Network Qt6::Xml Qt6::RemoteObjects Qt6::Network Qt6::Xml Qt6::RemoteObjects
Qt6::Quick Qt6::Svg Qt6::QuickControls2 Qt6::Quick Qt6::Svg Qt6::QuickControls2
Qt6::Core5Compat Qt6::Core5Compat Qt6::Concurrent
) )
qt_standard_project_setup() qt_standard_project_setup()

View file

@ -31,6 +31,7 @@ enum ErrorCode
ServerPortAlreadyAllocatedError, ServerPortAlreadyAllocatedError,
ServerContainerMissingError, ServerContainerMissingError,
ServerDockerFailedError, ServerDockerFailedError,
ServerCancelInstallation,
// Ssh connection errors // Ssh connection errors
SshSocketError, SshTimeoutError, SshProtocolError, SshSocketError, SshTimeoutError, SshProtocolError,

View file

@ -15,6 +15,7 @@ QString errorString(ErrorCode code){
case(ServerPortAlreadyAllocatedError): return QObject::tr("Server port already used. Check for another software"); case(ServerPortAlreadyAllocatedError): return QObject::tr("Server port already used. Check for another software");
case(ServerContainerMissingError): return QObject::tr("Server error: Docker container missing"); case(ServerContainerMissingError): return QObject::tr("Server error: Docker container missing");
case(ServerDockerFailedError): return QObject::tr("Server error: Docker failed"); case(ServerDockerFailedError): return QObject::tr("Server error: Docker failed");
case(ServerCancelInstallation): return QObject::tr("Installation canceled by user");
// Ssh connection errors // Ssh connection errors
case(SshSocketError): return QObject::tr("Ssh connection error"); case(SshSocketError): return QObject::tr("Ssh connection error");

View file

@ -31,6 +31,7 @@ QString amnezia::scriptName(SharedScriptType type)
case SharedScriptType::remove_all_containers: return QLatin1String("remove_all_containers.sh"); case SharedScriptType::remove_all_containers: return QLatin1String("remove_all_containers.sh");
case SharedScriptType::setup_host_firewall: return QLatin1String("setup_host_firewall.sh"); case SharedScriptType::setup_host_firewall: return QLatin1String("setup_host_firewall.sh");
case SharedScriptType::check_connection: return QLatin1String("check_connection.sh"); case SharedScriptType::check_connection: return QLatin1String("check_connection.sh");
case SharedScriptType::check_server_is_busy: return QLatin1String("check_server_is_busy.sh");
} }
} }

View file

@ -15,7 +15,8 @@ enum SharedScriptType {
remove_container, remove_container,
remove_all_containers, remove_all_containers,
setup_host_firewall, setup_host_firewall,
check_connection check_connection,
check_server_is_busy
}; };
enum ProtocolScriptType { enum ProtocolScriptType {
// Protocol scripts // Protocol scripts

View file

@ -12,6 +12,8 @@
#include <QApplication> #include <QApplication>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QFileInfo> #include <QFileInfo>
#include <QThread>
#include <QtConcurrent>
#include "sftpchannel.h" #include "sftpchannel.h"
#include "sshconnectionmanager.h" #include "sshconnectionmanager.h"
@ -528,14 +530,45 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent
stdOut += data + "\n"; stdOut += data + "\n";
}; };
ErrorCode e = runScript(credentials, QFutureWatcher<ErrorCode> watcher;
replaceVars(amnezia::scriptData(SharedScriptType::install_docker),
genVarsForScript(credentials)), QFuture<ErrorCode> future = QtConcurrent::run([this, &stdOut, &cbReadStdOut, &cbReadStdErr, &credentials]() {
cbReadStdOut, cbReadStdErr); do {
if (m_cancelInstallation) {
return ErrorCode::ServerCancelInstallation;
}
stdOut.clear();
runScript(credentials,
replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy),
genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
if (!stdOut.isEmpty() || stdOut.contains("Unable to acquire the dpkg frontend lock")) {
emit serverIsBusy(true);
QThread::msleep(1000);
}
} while (!stdOut.isEmpty());
return ErrorCode::NoError;
});
watcher.setFuture(future);
QEventLoop wait;
QObject::connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
wait.exec();
m_cancelInstallation = false;
emit serverIsBusy(false);
if (future.result() != ErrorCode::NoError) {
return future.result();
}
ErrorCode error = runScript(credentials,
replaceVars(amnezia::scriptData(SharedScriptType::install_docker),
genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
if (stdOut.contains("command not found")) return ErrorCode::ServerDockerFailedError; if (stdOut.contains("command not found")) return ErrorCode::ServerDockerFailedError;
return e; return error;
} }
ErrorCode ServerController::prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config) ErrorCode ServerController::prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
@ -796,6 +829,11 @@ SshConnection *ServerController::connectToHost(const SshConnectionParameters &ss
return client; return client;
} }
void ServerController::setCancelInstallation(const bool cancel)
{
m_cancelInstallation = cancel;
}
void ServerController::disconnectFromHost(const ServerCredentials &credentials) void ServerController::disconnectFromHost(const ServerCredentials &credentials)
{ {
SshConnection *client = acquireConnection(sshParams(credentials)); SshConnection *client = acquireConnection(sshParams(credentials));

View file

@ -73,6 +73,7 @@ public:
QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr); QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams); QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
void setCancelInstallation(const bool cancel);
private: private:
ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
@ -84,6 +85,10 @@ private:
std::shared_ptr<Settings> m_settings; std::shared_ptr<Settings> m_settings;
std::shared_ptr<VpnConfigurator> m_configurator; std::shared_ptr<VpnConfigurator> m_configurator;
bool m_cancelInstallation = false;
signals:
void serverIsBusy(const bool isBusy);
}; };
#endif // SERVERCONTROLLER_H #endif // SERVERCONTROLLER_H

View file

@ -129,6 +129,7 @@
<file>ui/qml/Controls/SvgButtonType.qml</file> <file>ui/qml/Controls/SvgButtonType.qml</file>
<file>ui/qml/Config/GlobalConfig.qml</file> <file>ui/qml/Config/GlobalConfig.qml</file>
<file>ui/qml/Config/qmldir</file> <file>ui/qml/Config/qmldir</file>
<file>server_scripts/check_server_is_busy.sh</file>
<file>server_scripts/dns/configure_container.sh</file> <file>server_scripts/dns/configure_container.sh</file>
<file>server_scripts/dns/Dockerfile</file> <file>server_scripts/dns/Dockerfile</file>
<file>server_scripts/dns/run_container.sh</file> <file>server_scripts/dns/run_container.sh</file>

View file

@ -0,0 +1,4 @@
pm_apt="/usr/bin/apt-get";\
if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else exit; fi;\
if [[ ! -f "/usr/bin/sudo" ]]; then $pm update -y -q; $pm install -y -q sudo; fi;\
sudo fuser /var/lib/dpkg/lock-frontend

View file

@ -5,6 +5,8 @@
#include <QEventLoop> #include <QEventLoop>
#include <QMessageBox> #include <QMessageBox>
#include "core/servercontroller.h"
ServerConfiguringProgressLogic::ServerConfiguringProgressLogic(UiLogic *logic, QObject *parent): ServerConfiguringProgressLogic::ServerConfiguringProgressLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent), PageLogicBase(logic, parent),
m_progressBarValue{0}, m_progressBarValue{0},
@ -13,7 +15,9 @@ ServerConfiguringProgressLogic::ServerConfiguringProgressLogic(UiLogic *logic, Q
m_progressBarVisible{true}, m_progressBarVisible{true},
m_progressBarMaximium{100}, m_progressBarMaximium{100},
m_progressBarTextVisible{true}, m_progressBarTextVisible{true},
m_progressBarText{tr("Configuring...")} m_progressBarText{tr("Configuring...")},
m_labelServerBusyVisible{false},
m_labelServerBusyText{""}
{ {
} }
@ -30,14 +34,14 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
page.setEnabledFunc = [this] (bool enabled) -> void { page.setEnabledFunc = [this] (bool enabled) -> void {
set_pageEnabled(enabled); set_pageEnabled(enabled);
}; };
ButtonFunc button; ButtonFunc noButton;
LabelFunc info; LabelFunc noWaitInfo;
ProgressFunc progress; ProgressFunc progress;
progress.setVisibleFunc = [this] (bool visible) ->void { progress.setVisibleFunc = [this] (bool visible) -> void {
set_progressBarVisible(visible); set_progressBarVisible(visible);
}; };
progress.setValueFunc = [this] (int value) ->void { progress.setValueFunc = [this] (int value) -> void {
set_progressBarValue(value); set_progressBarValue(value);
}; };
progress.getValueFunc = [this] (void) -> int { progress.getValueFunc = [this] (void) -> int {
@ -47,20 +51,42 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
return progressBarMaximium(); return progressBarMaximium();
}; };
LabelFunc busyInfo;
busyInfo.setTextFunc = [this] (const QString& text) -> void {
set_labelServerBusyText(text);
};
busyInfo.setVisibleFunc = [this] (bool visible) -> void {
set_labelServerBusyVisible(visible);
};
ButtonFunc cancelButton;
cancelButton.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonCancelVisible(visible);
};
return doInstallAction(action, page, progress, noButton, noWaitInfo, busyInfo, cancelButton);
}
ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<ErrorCode()> &action,
const PageFunc &page,
const ProgressFunc &progress,
const ButtonFunc &saveButton,
const LabelFunc &waitInfo,
const LabelFunc &serverBusyInfo,
const ButtonFunc &cancelButton)
{
progress.setVisibleFunc(true); progress.setVisibleFunc(true);
if (page.setEnabledFunc) { if (page.setEnabledFunc) {
page.setEnabledFunc(false); page.setEnabledFunc(false);
} }
if (button.setVisibleFunc) { if (saveButton.setVisibleFunc) {
button.setVisibleFunc(false); saveButton.setVisibleFunc(false);
} }
if (info.setVisibleFunc) { if (waitInfo.setVisibleFunc) {
info.setVisibleFunc(true); waitInfo.setVisibleFunc(true);
} }
if (info.setTextFunc) { if (waitInfo.setTextFunc) {
info.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes")); waitInfo.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes"));
} }
QTimer timer; QTimer timer;
@ -71,18 +97,50 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
progress.setValueFunc(0); progress.setValueFunc(0);
timer.start(1000); timer.start(1000);
QMetaObject::Connection cancelDoInstallActionConnection;
if (cancelButton.setVisibleFunc) {
cancelDoInstallActionConnection = connect(this, &ServerConfiguringProgressLogic::cancelDoInstallAction,
m_serverController.get(), &ServerController::setCancelInstallation);
}
QMetaObject::Connection serverBusyConnection;
if (serverBusyInfo.setVisibleFunc && serverBusyInfo.setTextFunc) {
serverBusyConnection = connect(m_serverController.get(),
&ServerController::serverIsBusy,
this,
[&serverBusyInfo, &timer, &cancelButton](const bool isBusy) {
isBusy ? timer.stop() : timer.start(1000);
serverBusyInfo.setVisibleFunc(isBusy);
serverBusyInfo.setTextFunc(isBusy ? "Amnesia has detected that your server is currently "
"busy installing other software. Amnesia installation "
"will pause until the server finishes installing other software"
: "");
if (cancelButton.setVisibleFunc) {
cancelButton.setVisibleFunc(isBusy ? true : false);
}
});
}
ErrorCode e = action(); ErrorCode e = action();
qDebug() << "doInstallAction finished with code" << e; qDebug() << "doInstallAction finished with code" << e;
if (cancelButton.setVisibleFunc) {
disconnect(cancelDoInstallActionConnection);
}
if (serverBusyInfo.setVisibleFunc && serverBusyInfo.setTextFunc) {
disconnect(serverBusyConnection);
}
if (e) { if (e) {
if (page.setEnabledFunc) { if (page.setEnabledFunc) {
page.setEnabledFunc(true); page.setEnabledFunc(true);
} }
if (button.setVisibleFunc) { if (saveButton.setVisibleFunc) {
button.setVisibleFunc(true); saveButton.setVisibleFunc(true);
} }
if (info.setVisibleFunc) { if (waitInfo.setVisibleFunc) {
info.setVisibleFunc(false); waitInfo.setVisibleFunc(false);
} }
QMessageBox::warning(nullptr, APPLICATION_NAME, QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" + tr("Error occurred while configuring server.") + "\n" +
@ -95,9 +153,9 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
// just ui progressbar tweak // just ui progressbar tweak
timer.stop(); timer.stop();
int remaining_val = progress.getMaximiumFunc() - progress.getValueFunc(); int remainingVal = progress.getMaximiumFunc() - progress.getValueFunc();
if (remaining_val > 0) { if (remainingVal > 0) {
QTimer timer1; QTimer timer1;
QEventLoop loop1; QEventLoop loop1;
@ -114,14 +172,19 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
progress.setVisibleFunc(false); progress.setVisibleFunc(false);
if (button.setVisibleFunc) { if (saveButton.setVisibleFunc) {
button.setVisibleFunc(true); saveButton.setVisibleFunc(true);
} }
if (page.setEnabledFunc) { if (page.setEnabledFunc) {
page.setEnabledFunc(true); page.setEnabledFunc(true);
} }
if (info.setTextFunc) { if (waitInfo.setTextFunc) {
info.setTextFunc(tr("Operation finished")); waitInfo.setTextFunc(tr("Operation finished"));
} }
return ErrorCode::NoError; return ErrorCode::NoError;
} }
void ServerConfiguringProgressLogic::onPushButtonCancelClicked()
{
cancelDoInstallAction(true);
}

View file

@ -20,13 +20,12 @@ class ServerConfiguringProgressLogic : public PageLogicBase
AUTO_PROPERTY(int, progressBarMaximium) AUTO_PROPERTY(int, progressBarMaximium)
AUTO_PROPERTY(bool, progressBarTextVisible) AUTO_PROPERTY(bool, progressBarTextVisible)
AUTO_PROPERTY(QString, progressBarText) AUTO_PROPERTY(QString, progressBarText)
AUTO_PROPERTY(bool, labelServerBusyVisible)
AUTO_PROPERTY(QString, labelServerBusyText)
AUTO_PROPERTY(bool, pushButtonCancelVisible)
public: public:
explicit ServerConfiguringProgressLogic(UiLogic *uiLogic, QObject *parent = nullptr); Q_INVOKABLE void onPushButtonCancelClicked();
~ServerConfiguringProgressLogic() = default;
void onUpdatePage() override;
ErrorCode doInstallAction(const std::function<ErrorCode()> &action);
private: private:
struct ProgressFunc { struct ProgressFunc {
@ -48,5 +47,27 @@ private:
std::function<void(const QString&)> setTextFunc; std::function<void(const QString&)> setTextFunc;
}; };
public:
explicit ServerConfiguringProgressLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~ServerConfiguringProgressLogic() = default;
friend class OpenVpnLogic;
friend class ShadowSocksLogic;
friend class CloakLogic;
friend class UiLogic;
void onUpdatePage() override;
ErrorCode doInstallAction(const std::function<ErrorCode()> &action);
ErrorCode doInstallAction(const std::function<ErrorCode()> &action,
const PageFunc &page,
const ProgressFunc &progress,
const ButtonFunc &saveButton,
const LabelFunc &waitInfo,
const LabelFunc &serverBusyInfo,
const ButtonFunc &cancelButton);
signals:
void cancelDoInstallAction(const bool cancel);
}; };
#endif // SERVER_CONFIGURING_PROGRESS_LOGIC_H #endif // SERVER_CONFIGURING_PROGRESS_LOGIC_H

View file

@ -1,7 +1,10 @@
#include "CloakLogic.h" #include "CloakLogic.h"
#include "core/servercontroller.h"
#include <functional> #include <functional>
#include "../../uilogic.h"
#include "core/servercontroller.h"
#include "ui/uilogic.h"
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
using namespace amnezia; using namespace amnezia;
using namespace PageEnumNS; using namespace PageEnumNS;
@ -59,40 +62,65 @@ void CloakLogic::onPushButtonSaveClicked()
QJsonObject newContainerConfig = containerConfig; QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig); newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig);
UiLogic::PageFunc page_func; ServerConfiguringProgressLogic::PageFunc pageFunc;
page_func.setEnabledFunc = [this] (bool enabled) -> void { pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
set_pageEnabled(enabled); set_pageEnabled(enabled);
}; };
UiLogic::ButtonFunc pushButton_save_func; ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc;
pushButton_save_func.setVisibleFunc = [this] (bool visible) ->void { saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonSaveVisible(visible); set_pushButtonSaveVisible(visible);
}; };
UiLogic::LabelFunc label_info_func; ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
label_info_func.setVisibleFunc = [this] (bool visible) ->void { waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
set_labelInfoVisible(visible); set_labelInfoVisible(visible);
}; };
label_info_func.setTextFunc = [this] (const QString& text) ->void { waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
set_labelInfoText(text); set_labelInfoText(text);
}; };
UiLogic::ProgressFunc progressBar_reset; ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
progressBar_reset.setVisibleFunc = [this] (bool visible) ->void { progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
set_progressBarResetVisible(visible); set_progressBarResetVisible(visible);
}; };
progressBar_reset.setValueFunc = [this] (int value) ->void { progressBarFunc.setValueFunc = [this] (int value) -> void {
set_progressBarResetValue(value); set_progressBarResetValue(value);
}; };
progressBar_reset.getValueFunc = [this] (void) -> int { progressBarFunc.getValueFunc = [this] (void) -> int {
return progressBarResetValue(); return progressBarResetValue();
}; };
progressBar_reset.getMaximiumFunc = [this] (void) -> int { progressBarFunc.getMaximiumFunc = [this] (void) -> int {
return progressBarResetMaximium(); return progressBarResetMaximium();
}; };
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
set_progressBarTextVisible(visible);
};
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
set_progressBarText(text);
};
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy;
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void {
set_labelServerBusyText(text);
};
busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void {
set_labelServerBusyVisible(visible);
};
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonCancelVisible(visible);
};
progressBarFunc.setTextVisibleFunc(true);
progressBarFunc.setTextFunc(QString("Configuring..."));
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, containerConfig, &newContainerConfig](){
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
uiLogic()->selectedDockerContainer,
containerConfig,
newContainerConfig);
}, },
page_func, progressBar_reset, pageFunc, progressBarFunc,
pushButton_save_func, label_info_func); saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
if (!e) { if (!e) {
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
@ -101,3 +129,8 @@ void CloakLogic::onPushButtonSaveClicked()
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
} }
void CloakLogic::onPushButtonCancelClicked()
{
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
}

View file

@ -20,9 +20,17 @@ class CloakLogic : public PageProtocolLogicBase
AUTO_PROPERTY(QString, labelInfoText) AUTO_PROPERTY(QString, labelInfoText)
AUTO_PROPERTY(int, progressBarResetValue) AUTO_PROPERTY(int, progressBarResetValue)
AUTO_PROPERTY(int, progressBarResetMaximium) AUTO_PROPERTY(int, progressBarResetMaximium)
AUTO_PROPERTY(bool, progressBarTextVisible)
AUTO_PROPERTY(QString, progressBarText)
AUTO_PROPERTY(bool, labelServerBusyVisible)
AUTO_PROPERTY(QString, labelServerBusyText)
AUTO_PROPERTY(bool, pushButtonCancelVisible)
public: public:
Q_INVOKABLE void onPushButtonSaveClicked(); Q_INVOKABLE void onPushButtonSaveClicked();
Q_INVOKABLE void onPushButtonCancelClicked();
public: public:
explicit CloakLogic(UiLogic *uiLogic, QObject *parent = nullptr); explicit CloakLogic(UiLogic *uiLogic, QObject *parent = nullptr);

View file

@ -1,7 +1,10 @@
#include "OpenVpnLogic.h" #include "OpenVpnLogic.h"
#include "core/servercontroller.h"
#include <functional> #include <functional>
#include "../../uilogic.h"
#include "core/servercontroller.h"
#include "ui/uilogic.h"
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
using namespace amnezia; using namespace amnezia;
using namespace PageEnumNS; using namespace PageEnumNS;
@ -100,7 +103,7 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo
set_isThirdPartyConfig(openvpnConfig.value(config_key::isThirdPartyConfig).isBool()); set_isThirdPartyConfig(openvpnConfig.value(config_key::isThirdPartyConfig).isBool());
} }
void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() void OpenVpnLogic::onPushButtonSaveClicked()
{ {
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn); QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn);
protocolConfig = getProtocolConfigFromPage(protocolConfig); protocolConfig = getProtocolConfigFromPage(protocolConfig);
@ -109,40 +112,65 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
QJsonObject newContainerConfig = containerConfig; QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig); newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig);
UiLogic::PageFunc page_proto_openvpn; ServerConfiguringProgressLogic::PageFunc pageFunc;
page_proto_openvpn.setEnabledFunc = [this] (bool enabled) -> void { pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
set_pageEnabled(enabled); set_pageEnabled(enabled);
}; };
UiLogic::ButtonFunc pushButton_proto_openvpn_save; ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc;
pushButton_proto_openvpn_save.setVisibleFunc = [this] (bool visible) ->void { saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonSaveVisible(visible); set_pushButtonSaveVisible(visible);
}; };
UiLogic::LabelFunc label_proto_openvpn_info; ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
label_proto_openvpn_info.setVisibleFunc = [this] (bool visible) ->void { waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
set_labelProtoOpenVpnInfoVisible(visible); set_labelProtoOpenVpnInfoVisible(visible);
}; };
label_proto_openvpn_info.setTextFunc = [this] (const QString& text) ->void { waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
set_labelProtoOpenVpnInfoText(text); set_labelProtoOpenVpnInfoText(text);
}; };
UiLogic::ProgressFunc progressBar_proto_openvpn_reset; ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
progressBar_proto_openvpn_reset.setVisibleFunc = [this] (bool visible) ->void { progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
set_progressBarResetVisible(visible); set_progressBarResetVisible(visible);
}; };
progressBar_proto_openvpn_reset.setValueFunc = [this] (int value) ->void { progressBarFunc.setValueFunc = [this] (int value) -> void {
set_progressBarResetValue(value); set_progressBarResetValue(value);
}; };
progressBar_proto_openvpn_reset.getValueFunc = [this] (void) -> int { progressBarFunc.getValueFunc = [this] (void) -> int {
return progressBarResetValue(); return progressBarResetValue();
}; };
progressBar_proto_openvpn_reset.getMaximiumFunc = [this] (void) -> int { progressBarFunc.getMaximiumFunc = [this] (void) -> int {
return progressBarResetMaximium(); return progressBarResetMaximium();
}; };
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
set_progressBarTextVisible(visible);
};
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
set_progressBarText(text);
};
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy;
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void {
set_labelServerBusyText(text);
};
busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void {
set_labelServerBusyVisible(visible);
};
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonCancelVisible(visible);
};
progressBarFunc.setTextVisibleFunc(true);
progressBarFunc.setTextFunc(QString("Configuring..."));
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, containerConfig, &newContainerConfig](){
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
uiLogic()->selectedDockerContainer,
containerConfig,
newContainerConfig);
}, },
page_proto_openvpn, progressBar_proto_openvpn_reset, pageFunc, progressBarFunc,
pushButton_proto_openvpn_save, label_proto_openvpn_info); saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
if (!e) { if (!e) {
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
@ -167,3 +195,8 @@ QJsonObject OpenVpnLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
oldConfig.insert(config_key::additional_server_config, textAreaAdditionalServerConfig()); oldConfig.insert(config_key::additional_server_config, textAreaAdditionalServerConfig());
return oldConfig; return oldConfig;
} }
void OpenVpnLogic::onPushButtonCancelClicked()
{
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
}

View file

@ -34,12 +34,20 @@ class OpenVpnLogic : public PageProtocolLogicBase
AUTO_PROPERTY(QString, labelProtoOpenVpnInfoText) AUTO_PROPERTY(QString, labelProtoOpenVpnInfoText)
AUTO_PROPERTY(int, progressBarResetValue) AUTO_PROPERTY(int, progressBarResetValue)
AUTO_PROPERTY(int, progressBarResetMaximium) AUTO_PROPERTY(int, progressBarResetMaximium)
AUTO_PROPERTY(bool, progressBarTextVisible)
AUTO_PROPERTY(QString, progressBarText)
AUTO_PROPERTY(bool, labelServerBusyVisible)
AUTO_PROPERTY(QString, labelServerBusyText)
AUTO_PROPERTY(bool, pushButtonCancelVisible)
AUTO_PROPERTY(QString, openVpnLastConfigText) AUTO_PROPERTY(QString, openVpnLastConfigText)
AUTO_PROPERTY(bool, isThirdPartyConfig) AUTO_PROPERTY(bool, isThirdPartyConfig)
public: public:
Q_INVOKABLE void onPushButtonProtoOpenVpnSaveClicked(); Q_INVOKABLE void onPushButtonSaveClicked();
Q_INVOKABLE void onPushButtonCancelClicked();
public: public:
explicit OpenVpnLogic(UiLogic *uiLogic, QObject *parent = nullptr); explicit OpenVpnLogic(UiLogic *uiLogic, QObject *parent = nullptr);

View file

@ -1,7 +1,10 @@
#include "ShadowSocksLogic.h" #include "ShadowSocksLogic.h"
#include "core/servercontroller.h"
#include <functional> #include <functional>
#include "../../uilogic.h"
#include "core/servercontroller.h"
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
#include "ui/uilogic.h"
using namespace amnezia; using namespace amnezia;
using namespace PageEnumNS; using namespace PageEnumNS;
@ -11,12 +14,12 @@ ShadowSocksLogic::ShadowSocksLogic(UiLogic *logic, QObject *parent):
m_comboBoxCipherText{"chacha20-poly1305"}, m_comboBoxCipherText{"chacha20-poly1305"},
m_lineEditPortText{}, m_lineEditPortText{},
m_pushButtonSaveVisible{false}, m_pushButtonSaveVisible{false},
m_progressBaResetVisible{false}, m_progressBarResetVisible{false},
m_lineEditPortEnabled{false}, m_lineEditPortEnabled{false},
m_labelInfoVisible{true}, m_labelInfoVisible{true},
m_labelInfoText{}, m_labelInfoText{},
m_progressBaResetValue{0}, m_progressBarResetValue{0},
m_progressBaResetMaximium{100} m_progressBarResetMaximium{100}
{ {
} }
@ -25,7 +28,7 @@ void ShadowSocksLogic::updateProtocolPage(const QJsonObject &ssConfig, DockerCon
{ {
set_pageEnabled(haveAuthData); set_pageEnabled(haveAuthData);
set_pushButtonSaveVisible(haveAuthData); set_pushButtonSaveVisible(haveAuthData);
set_progressBaResetVisible(haveAuthData); set_progressBarResetVisible(haveAuthData);
set_comboBoxCipherText(ssConfig.value(config_key::cipher). set_comboBoxCipherText(ssConfig.value(config_key::cipher).
toString(protocols::shadowsocks::defaultCipher)); toString(protocols::shadowsocks::defaultCipher));
@ -51,40 +54,65 @@ void ShadowSocksLogic::onPushButtonSaveClicked()
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject newContainerConfig = containerConfig; QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig); newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig);
UiLogic::PageFunc page_proto_shadowsocks; ServerConfiguringProgressLogic::PageFunc pageFunc;
page_proto_shadowsocks.setEnabledFunc = [this] (bool enabled) -> void { pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
set_pageEnabled(enabled); set_pageEnabled(enabled);
}; };
UiLogic::ButtonFunc pushButton_proto_shadowsocks_save; ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc;
pushButton_proto_shadowsocks_save.setVisibleFunc = [this] (bool visible) ->void { saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonSaveVisible(visible); set_pushButtonSaveVisible(visible);
}; };
UiLogic::LabelFunc label_proto_shadowsocks_info; ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
label_proto_shadowsocks_info.setVisibleFunc = [this] (bool visible) ->void { waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
set_labelInfoVisible(visible); set_labelInfoVisible(visible);
}; };
label_proto_shadowsocks_info.setTextFunc = [this] (const QString& text) ->void { waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
set_labelInfoText(text); set_labelInfoText(text);
}; };
UiLogic::ProgressFunc progressBar_reset; ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
progressBar_reset.setVisibleFunc = [this] (bool visible) ->void { progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
set_progressBaResetVisible(visible); set_progressBarResetVisible(visible);
}; };
progressBar_reset.setValueFunc = [this] (int value) ->void { progressBarFunc.setValueFunc = [this] (int value) -> void {
set_progressBaResetValue(value); set_progressBarResetValue(value);
}; };
progressBar_reset.getValueFunc = [this] (void) -> int { progressBarFunc.getValueFunc = [this] (void) -> int {
return progressBaResetValue(); return progressBarResetValue();
}; };
progressBar_reset.getMaximiumFunc = [this] (void) -> int { progressBarFunc.getMaximiumFunc = [this] (void) -> int {
return progressBaResetMaximium(); return progressBarResetMaximium();
};
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
set_progressBarTextVisible(visible);
};
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
set_progressBarText(text);
}; };
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy;
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void {
set_labelServerBusyText(text);
};
busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void {
set_labelServerBusyVisible(visible);
};
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
set_pushButtonCancelVisible(visible);
};
progressBarFunc.setTextVisibleFunc(true);
progressBarFunc.setTextFunc(QString("Configuring..."));
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, containerConfig, &newContainerConfig](){
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
uiLogic()->selectedDockerContainer,
containerConfig,
newContainerConfig);
}, },
page_proto_shadowsocks, progressBar_reset, pageFunc, progressBarFunc,
pushButton_proto_shadowsocks_save, label_proto_shadowsocks_info); saveButtonFunc, waitInfoFunc,
busyInfoFuncy, cancelButtonFunc);
if (!e) { if (!e) {
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
@ -92,3 +120,8 @@ void ShadowSocksLogic::onPushButtonSaveClicked()
} }
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
} }
void ShadowSocksLogic::onPushButtonCancelClicked()
{
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
}

View file

@ -12,15 +12,23 @@ class ShadowSocksLogic : public PageProtocolLogicBase
AUTO_PROPERTY(QString, comboBoxCipherText) AUTO_PROPERTY(QString, comboBoxCipherText)
AUTO_PROPERTY(QString, lineEditPortText) AUTO_PROPERTY(QString, lineEditPortText)
AUTO_PROPERTY(bool, pushButtonSaveVisible) AUTO_PROPERTY(bool, pushButtonSaveVisible)
AUTO_PROPERTY(bool, progressBaResetVisible) AUTO_PROPERTY(bool, progressBarResetVisible)
AUTO_PROPERTY(bool, lineEditPortEnabled) AUTO_PROPERTY(bool, lineEditPortEnabled)
AUTO_PROPERTY(bool, labelInfoVisible) AUTO_PROPERTY(bool, labelInfoVisible)
AUTO_PROPERTY(QString, labelInfoText) AUTO_PROPERTY(QString, labelInfoText)
AUTO_PROPERTY(int, progressBaResetValue) AUTO_PROPERTY(int, progressBarResetValue)
AUTO_PROPERTY(int, progressBaResetMaximium) AUTO_PROPERTY(int, progressBarResetMaximium)
AUTO_PROPERTY(bool, progressBarTextVisible)
AUTO_PROPERTY(QString, progressBarText)
AUTO_PROPERTY(bool, labelServerBusyVisible)
AUTO_PROPERTY(QString, labelServerBusyText)
AUTO_PROPERTY(bool, pushButtonCancelVisible)
public: public:
Q_INVOKABLE void onPushButtonSaveClicked(); Q_INVOKABLE void onPushButtonSaveClicked();
Q_INVOKABLE void onPushButtonCancelClicked();
public: public:
explicit ShadowSocksLogic(UiLogic *uiLogic, QObject *parent = nullptr); explicit ShadowSocksLogic(UiLogic *uiLogic, QObject *parent = nullptr);

View file

@ -10,7 +10,6 @@ PageBase {
page: PageEnum.ServerConfiguringProgress page: PageEnum.ServerConfiguringProgress
logic: ServerConfiguringProgressLogic logic: ServerConfiguringProgressLogic
enabled: ServerConfiguringProgressLogic.pageEnabled
Caption { Caption {
id: caption id: caption
text: qsTr("Configuring...") text: qsTr("Configuring...")
@ -27,6 +26,22 @@ PageBase {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
LabelType {
id: labelServerBusy
x: 0
anchors.top: label.bottom
anchors.topMargin: 30
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
width: parent.width - 40
height: 41
text: ServerConfiguringProgressLogic.labelServerBusyText
visible: ServerConfiguringProgressLogic.labelServerBusyVisible
}
LabelType { LabelType {
anchors.bottom: pr.top anchors.bottom: pr.top
anchors.bottomMargin: 20 anchors.bottomMargin: 20
@ -40,14 +55,27 @@ PageBase {
visible: ServerConfiguringProgressLogic.labelWaitInfoVisible visible: ServerConfiguringProgressLogic.labelWaitInfoVisible
} }
ProgressBar {
id: pr BlueButtonType {
id: pb_cancel
z: 1
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: logo.bottom anchors.bottom: logo.bottom
anchors.bottomMargin: 40 anchors.bottomMargin: 40
width: parent.width - 40 width: root.width - 60
height: 40 height: 40
text: qsTr("Cancel")
visible: ServerConfiguringProgressLogic.pushButtonCancelVisible
enabled: ServerConfiguringProgressLogic.pushButtonCancelVisible
onClicked: {
ServerConfiguringProgressLogic.onPushButtonCancelClicked()
}
}
ProgressBar {
id: pr
enabled: ServerConfiguringProgressLogic.pageEnabled
anchors.fill: pb_cancel
from: 0 from: 0
to: ServerConfiguringProgressLogic.progressBarMaximium to: ServerConfiguringProgressLogic.progressBarMaximium
value: ServerConfiguringProgressLogic.progressBarValue value: ServerConfiguringProgressLogic.progressBarValue

View file

@ -14,6 +14,7 @@ PageProtocolBase {
enabled: logic.pageEnabled enabled: logic.pageEnabled
BackButton { BackButton {
id: back id: back
enabled: logic.pageEnabled
} }
Caption { Caption {
@ -110,17 +111,24 @@ PageProtocolBase {
} }
} }
LabelType {
id: label_server_busy
horizontalAlignment: Text.AlignHCenter
Layout.maximumWidth: parent.width
Layout.fillWidth: true
visible: logic.labelServerBusyVisible
text: logic.labelServerBusyText
}
LabelType { LabelType {
id: label_proto_cloak_info id: label_proto_cloak_info
x: 30 horizontalAlignment: Text.AlignHCenter
anchors.bottom: pb_save.top Layout.maximumWidth: parent.width
anchors.bottomMargin: 10 Layout.fillWidth: true
width: parent.width - 40
visible: logic.labelInfoVisible visible: logic.labelInfoVisible
text: logic.labelInfoText text: logic.labelInfoText
} }
ProgressBar { ProgressBar {
id: progressBar_proto_cloak_reset id: progressBar_proto_cloak_reset
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
@ -146,6 +154,19 @@ PageProtocolBase {
} }
} }
visible: logic.progressBarResetVisible visible: logic.progressBarResetVisible
LabelType {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: logic.progressBarText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.family: "Lato"
font.styleName: "normal"
font.pixelSize: 16
color: "#D4D4D4"
visible: logic.progressBarTextVisible
}
} }
BlueButtonType { BlueButtonType {
id: pb_save id: pb_save
@ -162,4 +183,13 @@ PageProtocolBase {
} }
} }
BlueButtonType {
anchors.fill: pb_save
text: qsTr("Cancel")
visible: logic.pushButtonCancelVisible
enabled: logic.pushButtonCancelVisible
onClicked: {
logic.onPushButtonCancelClicked()
}
}
} }

View file

@ -13,7 +13,9 @@ PageProtocolBase {
BackButton { BackButton {
id: back id: back
enabled: logic.pageEnabled
} }
Caption { Caption {
id: caption id: caption
text: qsTr("OpenVPN Settings") text: qsTr("OpenVPN Settings")
@ -33,16 +35,17 @@ PageProtocolBase {
ColumnLayout { ColumnLayout {
visible: !logic.isThirdPartyConfig visible: !logic.isThirdPartyConfig
enabled: logic.pageEnabled
LabelType { LabelType {
id: lb_subnet id: lb_subnet
enabled: logic.pageEnabled
height: 21 height: 21
text: qsTr("VPN Addresses Subnet") text: qsTr("VPN Addresses Subnet")
} }
TextFieldType { TextFieldType {
id: tf_subnet id: tf_subnet
enabled: logic.pageEnabled
implicitWidth: parent.width implicitWidth: parent.width
height: 31 height: 31
text: logic.lineEditSubnetText text: logic.lineEditSubnetText
@ -51,15 +54,17 @@ PageProtocolBase {
} }
} }
//
LabelType { LabelType {
id: lb_proto id: lb_proto
enabled: logic.pageEnabled
Layout.topMargin: 20 Layout.topMargin: 20
height: 21 height: 21
text: qsTr("Network protocol") text: qsTr("Network protocol")
} }
Rectangle { Rectangle {
id: rect_proto id: rect_proto
enabled: logic.pageEnabled
implicitWidth: parent.width implicitWidth: parent.width
height: 71 height: 71
border.width: 1 border.width: 1
@ -91,8 +96,8 @@ PageProtocolBase {
} }
} }
//
RowLayout { RowLayout {
enabled: logic.pageEnabled
Layout.topMargin: 10 Layout.topMargin: 10
Layout.fillWidth: true Layout.fillWidth: true
LabelType { LabelType {
@ -114,12 +119,9 @@ PageProtocolBase {
} }
} }
//
CheckBoxType { CheckBoxType {
id: check_auto_enc id: check_auto_enc
enabled: logic.pageEnabled
implicitWidth: parent.width implicitWidth: parent.width
height: 21 height: 21
text: qsTr("Auto-negotiate encryption") text: qsTr("Auto-negotiate encryption")
@ -132,15 +134,16 @@ PageProtocolBase {
} }
} }
//
LabelType { LabelType {
id: lb_cipher id: lb_cipher
enabled: logic.pageEnabled
height: 21 height: 21
text: qsTr("Cipher") text: qsTr("Cipher")
} }
ComboBoxType { ComboBoxType {
id: cb_cipher id: cb_cipher
enabled: logic.pageEnabled && !check_auto_enc.checked
implicitWidth: parent.width implicitWidth: parent.width
height: 31 height: 31
@ -167,18 +170,19 @@ PageProtocolBase {
onCurrentTextChanged: { onCurrentTextChanged: {
logic.comboBoxVpnCipherText = currentText logic.comboBoxVpnCipherText = currentText
} }
enabled: !check_auto_enc.checked
} }
//
LabelType { LabelType {
id: lb_hash id: lb_hash
enabled: logic.pageEnabled
height: 21 height: 21
Layout.topMargin: 20 Layout.topMargin: 20
text: qsTr("Hash") text: qsTr("Hash")
} }
ComboBoxType { ComboBoxType {
id: cb_hash id: cb_hash
enabled: logic.pageEnabled && !check_auto_enc.checked
height: 31 height: 31
implicitWidth: parent.width implicitWidth: parent.width
model: [ model: [
@ -204,11 +208,11 @@ PageProtocolBase {
onCurrentTextChanged: { onCurrentTextChanged: {
logic.comboBoxVpnHashText = currentText logic.comboBoxVpnHashText = currentText
} }
enabled: !check_auto_enc.checked
} }
CheckBoxType { CheckBoxType {
id: check_tls id: check_tls
enabled: logic.pageEnabled
implicitWidth: parent.width implicitWidth: parent.width
Layout.topMargin: 20 Layout.topMargin: 20
height: 21 height: 21
@ -222,6 +226,7 @@ PageProtocolBase {
CheckBoxType { CheckBoxType {
id: check_block_dns id: check_block_dns
enabled: logic.pageEnabled
implicitWidth: parent.width implicitWidth: parent.width
height: 21 height: 21
text: qsTr("Block DNS requests outside of VPN") text: qsTr("Block DNS requests outside of VPN")
@ -231,10 +236,9 @@ PageProtocolBase {
} }
} }
BasicButtonType { BasicButtonType {
id: pb_client_config id: pb_client_config
enabled: logic.pageEnabled
implicitWidth: parent.width implicitWidth: parent.width
height: 21 height: 21
text: qsTr("Additional client config commands →") text: qsTr("Additional client config commands →")
@ -259,6 +263,7 @@ PageProtocolBase {
Rectangle { Rectangle {
id: rect_client_conf id: rect_client_conf
enabled: logic.pageEnabled
implicitWidth: root.width - 60 implicitWidth: root.width - 60
height: 101 height: 101
border.width: 1 border.width: 1
@ -284,10 +289,9 @@ PageProtocolBase {
} }
BasicButtonType { BasicButtonType {
id: pb_server_config id: pb_server_config
enabled: logic.pageEnabled
implicitWidth: parent.width implicitWidth: parent.width
height: 21 height: 21
text: qsTr("Additional server config commands →") text: qsTr("Additional server config commands →")
@ -312,6 +316,7 @@ PageProtocolBase {
Rectangle { Rectangle {
id: rect_server_conf id: rect_server_conf
enabled: logic.pageEnabled
implicitWidth: root.width - 60 implicitWidth: root.width - 60
height: 101 height: 101
border.width: 1 border.width: 1
@ -338,8 +343,21 @@ PageProtocolBase {
} }
LabelType { LabelType {
id: label_proto_openvpn_info id: label_server_busy
enabled: logic.pageEnabled
horizontalAlignment: Text.AlignHCenter
Layout.maximumWidth: parent.width
Layout.fillWidth: true
visible: logic.labelServerBusyVisible
text: logic.labelServerBusyText
}
LabelType {
id: label_proto_openvpn_info
enabled: logic.pageEnabled
horizontalAlignment: Text.AlignHCenter
Layout.maximumWidth: parent.width
Layout.fillWidth: true
height: 41 height: 41
visible: logic.labelProtoOpenVpnInfoVisible visible: logic.labelProtoOpenVpnInfoVisible
text: logic.labelProtoOpenVpnInfoText text: logic.labelProtoOpenVpnInfoText
@ -353,13 +371,25 @@ PageProtocolBase {
BlueButtonType { BlueButtonType {
id: pb_save id: pb_save
enabled: logic.pageEnabled
z: 1 z: 1
height: 40 height: 40
text: qsTr("Save and restart VPN") text: qsTr("Save and restart VPN")
width: parent.width width: parent.width
visible: logic.pushButtonSaveVisible visible: logic.pushButtonSaveVisible
onClicked: { onClicked: {
logic.onPushButtonProtoOpenVpnSaveClicked() logic.onPushButtonSaveClicked()
}
}
BlueButtonType {
z: 1
anchors.fill: pb_save
text: qsTr("Cancel")
visible: logic.pushButtonCancelVisible
enabled: logic.pushButtonCancelVisible
onClicked: {
logic.onPushButtonCancelClicked()
} }
} }
@ -389,6 +419,19 @@ PageProtocolBase {
} }
} }
LabelType {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: logic.progressBarText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.family: "Lato"
font.styleName: "normal"
font.pixelSize: 16
color: "#D4D4D4"
visible: logic.progressBarTextVisible
}
} }
} }
@ -412,5 +455,4 @@ PageProtocolBase {
} }
} }
} }
} }

View file

@ -13,6 +13,7 @@ PageProtocolBase {
BackButton { BackButton {
id: back id: back
enabled: logic.pageEnabled
} }
Caption { Caption {
@ -88,27 +89,33 @@ PageProtocolBase {
Item { Item {
Layout.fillHeight: true Layout.fillHeight: true
} }
}
LabelType {
id: label_server_busy
horizontalAlignment: Text.AlignHCenter
Layout.maximumWidth: parent.width
Layout.fillWidth: true
visible: logic.labelServerBusyVisible
text: logic.labelServerBusyText
}
LabelType { LabelType {
id: label_proto_shadowsocks_info id: label_proto_shadowsocks_info
x: 30 horizontalAlignment: Text.AlignHCenter
anchors.bottom: pb_save.top Layout.maximumWidth: parent.width
anchors.bottomMargin: 10 Layout.fillWidth: true
width: parent.width - 40 visible: logic.labelInfoVisible
height: 41 text: logic.labelInfoText
visible: logic.labelInfoVisible }
text: logic.labelInfoText
} }
ProgressBar { ProgressBar {
id: progressBar_reset id: progressBar_reset
anchors.fill: pb_save anchors.fill: pb_save
from: 0 from: 0
to: logic.progressBaResetMaximium to: logic.progressBarResetMaximium
value: logic.progressBaResetValue value: logic.progressBarResetValue
visible: logic.progressBaResetVisible visible: logic.progressBarResetVisible
background: Rectangle { background: Rectangle {
implicitWidth: parent.width implicitWidth: parent.width
implicitHeight: parent.height implicitHeight: parent.height
@ -126,6 +133,19 @@ PageProtocolBase {
color: Qt.rgba(255, 255, 255, 0.15); color: Qt.rgba(255, 255, 255, 0.15);
} }
} }
LabelType {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: logic.progressBarText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.family: "Lato"
font.styleName: "normal"
font.pixelSize: 16
color: "#D4D4D4"
visible: logic.progressBarTextVisible
}
} }
BlueButtonType { BlueButtonType {
@ -142,4 +162,14 @@ PageProtocolBase {
logic.onPushButtonSaveClicked() logic.onPushButtonSaveClicked()
} }
} }
BlueButtonType {
anchors.fill: pb_save
text: qsTr("Cancel")
visible: logic.pushButtonCancelVisible
enabled: logic.pushButtonCancelVisible
onClicked: {
logic.onPushButtonCancelClicked()
}
}
} }

View file

@ -277,44 +277,67 @@ void UiLogic::installServer(QMap<DockerContainer, QJsonObject> &containers)
loop.exec(); loop.exec();
qApp->processEvents(); qApp->processEvents();
PageFunc page_new_server_configuring; ServerConfiguringProgressLogic::PageFunc pageFunc;
page_new_server_configuring.setEnabledFunc = [this] (bool enabled) -> void { pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_pageEnabled(enabled); pageLogic<ServerConfiguringProgressLogic>()->set_pageEnabled(enabled);
}; };
ButtonFunc no_button;
LabelFunc label_new_server_configuring_wait_info; ServerConfiguringProgressLogic::ButtonFunc noButton;
label_new_server_configuring_wait_info.setTextFunc = [this] (const QString& text) -> void {
ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_labelWaitInfoText(text); pageLogic<ServerConfiguringProgressLogic>()->set_labelWaitInfoText(text);
}; };
label_new_server_configuring_wait_info.setVisibleFunc = [this] (bool visible) ->void { waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_labelWaitInfoVisible(visible); pageLogic<ServerConfiguringProgressLogic>()->set_labelWaitInfoVisible(visible);
}; };
ProgressFunc progressBar_new_server_configuring;
progressBar_new_server_configuring.setVisibleFunc = [this] (bool visible) ->void { ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarVisible(visible); pageLogic<ServerConfiguringProgressLogic>()->set_progressBarVisible(visible);
}; };
progressBar_new_server_configuring.setValueFunc = [this] (int value) ->void { progressBarFunc.setValueFunc = [this] (int value) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarValue(value); pageLogic<ServerConfiguringProgressLogic>()->set_progressBarValue(value);
}; };
progressBar_new_server_configuring.getValueFunc = [this] (void) -> int { progressBarFunc.getValueFunc = [this] (void) -> int {
return pageLogic<ServerConfiguringProgressLogic>()->progressBarValue(); return pageLogic<ServerConfiguringProgressLogic>()->progressBarValue();
}; };
progressBar_new_server_configuring.getMaximiumFunc = [this] (void) -> int { progressBarFunc.getMaximiumFunc = [this] (void) -> int {
return pageLogic<ServerConfiguringProgressLogic>()->progressBarMaximium(); return pageLogic<ServerConfiguringProgressLogic>()->progressBarMaximium();
}; };
progressBar_new_server_configuring.setTextVisibleFunc = [this] (bool visible) ->void { progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarTextVisible(visible); pageLogic<ServerConfiguringProgressLogic>()->set_progressBarTextVisible(visible);
}; };
progressBar_new_server_configuring.setTextFunc = [this] (const QString& text) ->void { progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarText(text); pageLogic<ServerConfiguringProgressLogic>()->set_progressBarText(text);
}; };
bool ok = installContainers(installCredentials, containers,
page_new_server_configuring,
progressBar_new_server_configuring,
no_button,
label_new_server_configuring_wait_info);
if (ok) { ServerConfiguringProgressLogic::LabelFunc busyInfoFunc;
busyInfoFunc.setTextFunc = [this] (const QString& text) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_labelServerBusyText(text);
};
busyInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_labelServerBusyVisible(visible);
};
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
pageLogic<ServerConfiguringProgressLogic>()->set_pushButtonCancelVisible(visible);
};
int count = 0;
ErrorCode error;
for (QMap<DockerContainer, QJsonObject>::iterator i = containers.begin(); i != containers.end(); i++, count++) {
progressBarFunc.setTextFunc(QString("Installing %1 %2 %3").arg(count+1).arg(tr("of")).arg(containers.size()));
error = pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([&] () {
return m_serverController->setupContainer(installCredentials, i.key(), i.value());
}, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc, cancelButtonFunc);
m_serverController->disconnectFromHost(installCredentials);
}
if (error == ErrorCode::NoError) {
QJsonObject server; QJsonObject server;
server.insert(config_key::hostName, installCredentials.hostName); server.insert(config_key::hostName, installCredentials.hostName);
server.insert(config_key::userName, installCredentials.userName); server.insert(config_key::userName, installCredentials.userName);
@ -341,182 +364,6 @@ void UiLogic::installServer(QMap<DockerContainer, QJsonObject> &containers)
} }
} }
bool UiLogic::installContainers(ServerCredentials credentials,
QMap<DockerContainer, QJsonObject> &containers,
const PageFunc &page,
const ProgressFunc &progress,
const ButtonFunc &button,
const LabelFunc &info)
{
if (!progress.setValueFunc) return false;
if (page.setEnabledFunc) {
page.setEnabledFunc(false);
}
if (button.setVisibleFunc) {
button.setVisibleFunc(false);
}
if (info.setVisibleFunc) {
info.setVisibleFunc(true);
}
if (info.setTextFunc) {
info.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes"));
}
int cnt = 0;
for (QMap<DockerContainer, QJsonObject>::iterator i = containers.begin(); i != containers.end(); i++, cnt++) {
QTimer timer;
connect(&timer, &QTimer::timeout, [progress](){
progress.setValueFunc(progress.getValueFunc() + 1);
});
progress.setValueFunc(0);
timer.start(1000);
progress.setTextVisibleFunc(true);
progress.setTextFunc(QString("Installing %1 %2 %3").arg(cnt+1).arg(tr("of")).arg(containers.size()));
ErrorCode e = m_serverController->setupContainer(credentials, i.key(), i.value());
qDebug() << "Setup server finished with code" << e;
m_serverController->disconnectFromHost(credentials);
if (e) {
if (page.setEnabledFunc) {
page.setEnabledFunc(true);
}
if (button.setVisibleFunc) {
button.setVisibleFunc(true);
}
if (info.setVisibleFunc) {
info.setVisibleFunc(false);
}
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" +
errorString(e));
return false;
}
// just ui progressbar tweak
timer.stop();
int remaining_val = progress.getMaximiumFunc() - progress.getValueFunc();
if (remaining_val > 0) {
QTimer timer1;
QEventLoop loop1;
connect(&timer1, &QTimer::timeout, [&](){
progress.setValueFunc(progress.getValueFunc() + 1);
if (progress.getValueFunc() >= progress.getMaximiumFunc()) {
loop1.quit();
}
});
timer1.start(5);
loop1.exec();
}
}
if (button.setVisibleFunc) {
button.setVisibleFunc(true);
}
if (page.setEnabledFunc) {
page.setEnabledFunc(true);
}
if (info.setTextFunc) {
info.setTextFunc(tr("Amnezia server installed"));
}
return true;
}
ErrorCode UiLogic::doInstallAction(const std::function<ErrorCode()> &action,
const PageFunc &page,
const ProgressFunc &progress,
const ButtonFunc &button,
const LabelFunc &info)
{
progress.setVisibleFunc(true);
if (page.setEnabledFunc) {
page.setEnabledFunc(false);
}
if (button.setVisibleFunc) {
button.setVisibleFunc(false);
}
if (info.setVisibleFunc) {
info.setVisibleFunc(true);
}
if (info.setTextFunc) {
info.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes"));
}
QTimer timer;
connect(&timer, &QTimer::timeout, [progress](){
progress.setValueFunc(progress.getValueFunc() + 1);
});
progress.setValueFunc(0);
timer.start(1000);
ErrorCode e = action();
qDebug() << "doInstallAction finished with code" << e;
if (e) {
if (page.setEnabledFunc) {
page.setEnabledFunc(true);
}
if (button.setVisibleFunc) {
button.setVisibleFunc(true);
}
if (info.setVisibleFunc) {
info.setVisibleFunc(false);
}
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" +
errorString(e));
progress.setVisibleFunc(false);
return e;
}
// just ui progressbar tweak
timer.stop();
int remaining_val = progress.getMaximiumFunc() - progress.getValueFunc();
if (remaining_val > 0) {
QTimer timer1;
QEventLoop loop1;
connect(&timer1, &QTimer::timeout, [&](){
progress.setValueFunc(progress.getValueFunc() + 1);
if (progress.getValueFunc() >= progress.getMaximiumFunc()) {
loop1.quit();
}
});
timer1.start(5);
loop1.exec();
}
progress.setVisibleFunc(false);
if (button.setVisibleFunc) {
button.setVisibleFunc(true);
}
if (page.setEnabledFunc) {
page.setEnabledFunc(true);
}
if (info.setTextFunc) {
info.setTextFunc(tr("Operation finished"));
}
return ErrorCode::NoError;
}
PageProtocolLogicBase *UiLogic::protocolLogic(Proto p) PageProtocolLogicBase *UiLogic::protocolLogic(Proto p)
{ {
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p); PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);

View file

@ -136,38 +136,6 @@ private slots:
private: private:
PageEnumNS::Page currentPage(); PageEnumNS::Page currentPage();
struct ProgressFunc {
std::function<void(bool)> setVisibleFunc;
std::function<void(int)> setValueFunc;
std::function<int(void)> getValueFunc;
std::function<int(void)> getMaximiumFunc;
std::function<void(bool)> setTextVisibleFunc;
std::function<void(const QString&)> setTextFunc;
};
struct PageFunc {
std::function<void(bool)> setEnabledFunc;
};
struct ButtonFunc {
std::function<void(bool)> setVisibleFunc;
};
struct LabelFunc {
std::function<void(bool)> setVisibleFunc;
std::function<void(const QString&)> setTextFunc;
};
bool installContainers(ServerCredentials credentials,
QMap<DockerContainer, QJsonObject> &containers,
const PageFunc& page,
const ProgressFunc& progress,
const ButtonFunc& button,
const LabelFunc& info);
ErrorCode doInstallAction(const std::function<ErrorCode()> &action,
const PageFunc& page,
const ProgressFunc& progress,
const ButtonFunc& button,
const LabelFunc& info);
public: public:
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p); Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p);