Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-awg-docker-container
This commit is contained in:
commit
cd9cdd24ec
18 changed files with 229 additions and 28 deletions
|
@ -15,6 +15,15 @@ set(PACKAGES
|
||||||
Core5Compat Concurrent LinguistTools
|
Core5Compat Concurrent LinguistTools
|
||||||
)
|
)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
|
COMMAND git rev-parse --short HEAD
|
||||||
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
|
||||||
|
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
|
||||||
|
|
||||||
if(IOS)
|
if(IOS)
|
||||||
set(PACKAGES ${PACKAGES} Multimedia)
|
set(PACKAGES ${PACKAGES} Multimedia)
|
||||||
endif()
|
endif()
|
||||||
|
|
6
client/images/controls/split-tunneling.svg
Normal file
6
client/images/controls/split-tunneling.svg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="0.5" width="18" height="18" rx="5" fill="white"/>
|
||||||
|
<path d="M8.49219 13.5L8.49219 9.44141L14.0191 4.99484" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M4.47363 5.49805L6.98828 8.0127" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M14.4727 9.5L14.4727 4.5033L9.50195 4.5033" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 511 B |
|
@ -224,6 +224,8 @@
|
||||||
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
||||||
<file>images/controls/close.svg</file>
|
<file>images/controls/close.svg</file>
|
||||||
<file>images/controls/search.svg</file>
|
<file>images/controls/search.svg</file>
|
||||||
|
<file>ui/qml/Components/HomeSplitTunnelingDrawer.qml</file>
|
||||||
|
<file>images/controls/split-tunneling.svg</file>
|
||||||
<file>ui/qml/Controls2/DrawerType2.qml</file>
|
<file>ui/qml/Controls2/DrawerType2.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -997,6 +997,11 @@ And if you don't like the app, all the more support it - the donation will
|
||||||
<source>https://amnezia.org</source>
|
<source>https://amnezia.org</source>
|
||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
|
||||||
|
<source>Software version: %1</source>
|
||||||
|
<translation>%1 :إصدار البرنامج</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
|
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
|
||||||
<source>Check for updates</source>
|
<source>Check for updates</source>
|
||||||
|
@ -2999,11 +3004,6 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsController</name>
|
<name>SettingsController</name>
|
||||||
<message>
|
|
||||||
<location filename="../ui/controllers/settingsController.cpp" line="31"/>
|
|
||||||
<source>Software version</source>
|
|
||||||
<translation>إصدار البرنامج</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/controllers/settingsController.cpp" line="139"/>
|
<location filename="../ui/controllers/settingsController.cpp" line="139"/>
|
||||||
<source>Backup file is corrupted</source>
|
<source>Backup file is corrupted</source>
|
||||||
|
|
|
@ -1022,6 +1022,11 @@ Already installed containers were found on the server. All installed containers
|
||||||
<source>https://amnezia.org</source>
|
<source>https://amnezia.org</source>
|
||||||
<translation>https://amnezia.org</translation>
|
<translation>https://amnezia.org</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
|
||||||
|
<source>Software version: %1</source>
|
||||||
|
<translation>%1 :نسخه نرمافزار</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
|
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
|
||||||
<source>Check for updates</source>
|
<source>Check for updates</source>
|
||||||
|
@ -3107,11 +3112,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsController</name>
|
<name>SettingsController</name>
|
||||||
<message>
|
|
||||||
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
|
|
||||||
<source>Software version</source>
|
|
||||||
<translation>نسخه نرمافزار</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/controllers/settingsController.cpp" line="148"/>
|
<location filename="../ui/controllers/settingsController.cpp" line="148"/>
|
||||||
<source>All settings have been reset to default values</source>
|
<source>All settings have been reset to default values</source>
|
||||||
|
|
|
@ -1020,6 +1020,11 @@ Already installed containers were found on the server. All installed containers
|
||||||
<source>https://amnezia.org</source>
|
<source>https://amnezia.org</source>
|
||||||
<translation>https://amnezia.org</translation>
|
<translation>https://amnezia.org</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
|
||||||
|
<source>Software version: %1</source>
|
||||||
|
<translation>Версия ПО: %1</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
|
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
|
||||||
<source>Check for updates</source>
|
<source>Check for updates</source>
|
||||||
|
@ -3058,11 +3063,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsController</name>
|
<name>SettingsController</name>
|
||||||
<message>
|
|
||||||
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
|
|
||||||
<source>Software version</source>
|
|
||||||
<translation>Версия ПО</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/controllers/settingsController.cpp" line="148"/>
|
<location filename="../ui/controllers/settingsController.cpp" line="148"/>
|
||||||
<source>All settings have been reset to default values</source>
|
<source>All settings have been reset to default values</source>
|
||||||
|
|
|
@ -1067,6 +1067,11 @@ And if you don't like the app, all the more support it - the donation will
|
||||||
<source>https://amnezia.org</source>
|
<source>https://amnezia.org</source>
|
||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
|
||||||
|
<source>Software version: %1</source>
|
||||||
|
<translation>软件版本: %1</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
|
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
|
||||||
<source>Check for updates</source>
|
<source>Check for updates</source>
|
||||||
|
@ -3206,11 +3211,6 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsController</name>
|
<name>SettingsController</name>
|
||||||
<message>
|
|
||||||
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
|
|
||||||
<source>Software version</source>
|
|
||||||
<translation>软件版本</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/controllers/settingsController.cpp" line="132"/>
|
<location filename="../ui/controllers/settingsController.cpp" line="132"/>
|
||||||
<source>Backup file is corrupted</source>
|
<source>Backup file is corrupted</source>
|
||||||
|
|
|
@ -28,7 +28,7 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
|
||||||
m_sitesModel(sitesModel),
|
m_sitesModel(sitesModel),
|
||||||
m_settings(settings)
|
m_settings(settings)
|
||||||
{
|
{
|
||||||
m_appVersion = QString("%1: %2 (%3)").arg(tr("Software version"), QString(APP_VERSION), __DATE__);
|
m_appVersion = QString("%1 (%2, %3)").arg(QString(APP_VERSION), __DATE__, GIT_COMMIT_HASH);
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
if (!m_settings->isScreenshotsEnabled()) {
|
if (!m_settings->isScreenshotsEnabled()) {
|
||||||
|
|
|
@ -220,6 +220,11 @@ bool ServersModel::isDefaultServerCurrentlyProcessed()
|
||||||
return m_defaultServerIndex == m_processedServerIndex;
|
return m_defaultServerIndex == m_processedServerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ServersModel::isDefaultServerFromApi()
|
||||||
|
{
|
||||||
|
return qvariant_cast<bool>(data(m_defaultServerIndex, IsServerFromApiRole));
|
||||||
|
}
|
||||||
|
|
||||||
bool ServersModel::isProcessedServerHasWriteAccess()
|
bool ServersModel::isProcessedServerHasWriteAccess()
|
||||||
{
|
{
|
||||||
return qvariant_cast<bool>(data(m_processedServerIndex, HasWriteAccessRole));
|
return qvariant_cast<bool>(data(m_processedServerIndex, HasWriteAccessRole));
|
||||||
|
@ -249,7 +254,7 @@ void ServersModel::editServer(const QJsonObject &server, const int serverIndex)
|
||||||
}
|
}
|
||||||
updateContainersModel();
|
updateContainersModel();
|
||||||
|
|
||||||
if (isDefaultServerCurrentlyProcessed()) {
|
if (serverIndex == m_defaultServerIndex) {
|
||||||
auto defaultContainer = qvariant_cast<DockerContainer>(getDefaultServerData("defaultContainer"));
|
auto defaultContainer = qvariant_cast<DockerContainer>(getDefaultServerData("defaultContainer"));
|
||||||
emit defaultServerDefaultContainerChanged(defaultContainer);
|
emit defaultServerDefaultContainerChanged(defaultContainer);
|
||||||
}
|
}
|
||||||
|
@ -577,3 +582,18 @@ void ServersModel::setProcessedServerData(const QString roleString, const QVaria
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
|
||||||
|
{
|
||||||
|
auto server = m_servers.at(m_defaultServerIndex).toObject();
|
||||||
|
auto defaultContainer = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
|
||||||
|
auto containerConfig = server.value(config_key::containers).toArray().at(defaultContainer).toObject();
|
||||||
|
auto protocolConfig = containerConfig.value(ContainerProps::containerTypeToString(defaultContainer)).toObject();
|
||||||
|
|
||||||
|
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
|
||||||
|
return !(protocolConfig.value(config_key::last_config).toString().contains("AllowedIPs = 0.0.0.0/0, ::/0"));
|
||||||
|
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn || defaultContainer == DockerContainer::ShadowSocks) {
|
||||||
|
return !(protocolConfig.value(config_key::last_config).toString().contains("redirect-gateway"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@ public:
|
||||||
Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerDefaultContainerChanged)
|
Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerDefaultContainerChanged)
|
||||||
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDefaultContainerChanged)
|
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDefaultContainerChanged)
|
||||||
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDefaultContainerChanged)
|
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDefaultContainerChanged)
|
||||||
|
Q_PROPERTY(bool isDefaultServerDefaultContainerHasSplitTunneling READ isDefaultServerDefaultContainerHasSplitTunneling NOTIFY defaultServerDefaultContainerChanged)
|
||||||
|
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged)
|
||||||
|
|
||||||
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
||||||
|
|
||||||
|
@ -59,6 +61,7 @@ public slots:
|
||||||
const QString getDefaultServerDescriptionExpanded();
|
const QString getDefaultServerDescriptionExpanded();
|
||||||
const QString getDefaultServerDefaultContainerName();
|
const QString getDefaultServerDefaultContainerName();
|
||||||
bool isDefaultServerCurrentlyProcessed();
|
bool isDefaultServerCurrentlyProcessed();
|
||||||
|
bool isDefaultServerFromApi();
|
||||||
|
|
||||||
bool isProcessedServerHasWriteAccess();
|
bool isProcessedServerHasWriteAccess();
|
||||||
bool isDefaultServerHasWriteAccess();
|
bool isDefaultServerHasWriteAccess();
|
||||||
|
@ -103,6 +106,8 @@ public slots:
|
||||||
QVariant getProcessedServerData(const QString roleString);
|
QVariant getProcessedServerData(const QString roleString);
|
||||||
void setProcessedServerData(const QString roleString, const QVariant &value);
|
void setProcessedServerData(const QString roleString, const QVariant &value);
|
||||||
|
|
||||||
|
bool isDefaultServerDefaultContainerHasSplitTunneling();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ void SitesModel::toggleSplitTunneling(bool enabled)
|
||||||
m_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
|
m_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
|
||||||
}
|
}
|
||||||
m_isSplitTunnelingEnabled = enabled;
|
m_isSplitTunnelingEnabled = enabled;
|
||||||
|
emit splitTunnelingToggled();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QPair<QString, QString> > SitesModel::getCurrentSites()
|
QVector<QPair<QString, QString> > SitesModel::getCurrentSites()
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
Q_PROPERTY(int routeMode READ getRouteMode WRITE setRouteMode NOTIFY routeModeChanged)
|
Q_PROPERTY(int routeMode READ getRouteMode WRITE setRouteMode NOTIFY routeModeChanged)
|
||||||
|
Q_PROPERTY(bool isTunnelingEnabled READ isSplitTunnelingEnabled NOTIFY splitTunnelingToggled)
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool addSite(const QString &hostname, const QString &ip);
|
bool addSite(const QString &hostname, const QString &ip);
|
||||||
|
@ -38,6 +39,7 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void routeModeChanged();
|
void routeModeChanged();
|
||||||
|
void splitTunnelingToggled();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
92
client/ui/qml/Components/HomeSplitTunnelingDrawer.qml
Normal file
92
client/ui/qml/Components/HomeSplitTunnelingDrawer.qml
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import PageEnum 1.0
|
||||||
|
|
||||||
|
import "../Controls2"
|
||||||
|
import "../Controls2/TextTypes"
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
|
DrawerType2 {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
expandedHeight: parent.height * 0.7
|
||||||
|
|
||||||
|
expandedContent: ColumnLayout {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Header2Type {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.bottomMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Split tunneling")
|
||||||
|
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
|
||||||
|
|
||||||
|
text: qsTr("Split tunneling on the server")
|
||||||
|
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
|
||||||
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||||
|
// root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {
|
||||||
|
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
enabled: ! ServersModel.isDefaultServerDefaultContainerHasSplitTunneling || !ServersModel.getDefaultServerData("isServerFromApi")
|
||||||
|
|
||||||
|
text: qsTr("Site-based split tunneling")
|
||||||
|
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||||
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
text: qsTr("App-based split tunneling")
|
||||||
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
// PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ Button {
|
||||||
property int borderFocusedWidth: 1
|
property int borderFocusedWidth: 1
|
||||||
|
|
||||||
property string imageSource
|
property string imageSource
|
||||||
|
property string rightImageSource
|
||||||
|
property string leftImageColor: textColor
|
||||||
|
|
||||||
property bool squareLeftSide: false
|
property bool squareLeftSide: false
|
||||||
|
|
||||||
|
@ -118,7 +120,7 @@ Button {
|
||||||
layer {
|
layer {
|
||||||
enabled: true
|
enabled: true
|
||||||
effect: ColorOverlay {
|
effect: ColorOverlay {
|
||||||
color: textColor
|
color: leftImageColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,6 +133,21 @@ Button {
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
Layout.preferredHeight: 20
|
||||||
|
Layout.preferredWidth: 20
|
||||||
|
|
||||||
|
source: root.rightImageSource
|
||||||
|
visible: root.rightImageSource === "" ? false : true
|
||||||
|
|
||||||
|
layer {
|
||||||
|
enabled: true
|
||||||
|
effect: ColorOverlay {
|
||||||
|
color: textColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,45 @@ PageType {
|
||||||
anchors.bottomMargin: drawer.collapsedHeight
|
anchors.bottomMargin: drawer.collapsedHeight
|
||||||
|
|
||||||
ConnectButton {
|
ConnectButton {
|
||||||
|
id: connectButton
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 34
|
||||||
|
leftPadding: 16
|
||||||
|
rightPadding: 16
|
||||||
|
|
||||||
|
implicitHeight: 36
|
||||||
|
|
||||||
|
defaultColor: "transparent"
|
||||||
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
|
disabledColor: "#878B91"
|
||||||
|
textColor: "#878B91"
|
||||||
|
leftImageColor: "transparent"
|
||||||
|
borderWidth: 0
|
||||||
|
|
||||||
|
property bool isSplitTunnelingEnabled: SitesModel.isTunnelingEnabled ||
|
||||||
|
(ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi"))
|
||||||
|
|
||||||
|
text: isSplitTunnelingEnabled ? qsTr("Split tunneling enabled") : qsTr("Split tunneling disabled")
|
||||||
|
|
||||||
|
imageSource: isSplitTunnelingEnabled ? "qrc:/images/controls/split-tunneling.svg" : ""
|
||||||
|
rightImageSource: "qrc:/images/controls/chevron-down.svg"
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
homeSplitTunnelingDrawer.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
HomeSplitTunnelingDrawer {
|
||||||
|
id: homeSplitTunnelingDrawer
|
||||||
|
|
||||||
|
parent: root
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,7 +193,7 @@ PageType {
|
||||||
|
|
||||||
LabelTextType {
|
LabelTextType {
|
||||||
id: expandedServersMenuDescription
|
id: expandedServersMenuDescription
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: ServersModel.isDefaultServerFromApi ? 69 : 24
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
horizontalAlignment: Qt.AlignHCenter
|
||||||
verticalAlignment: Qt.AlignVCenter
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
@ -167,6 +204,9 @@ PageType {
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
|
visible: !ServersModel.isDefaultServerFromApi
|
||||||
|
onVisibleChanged: expandedServersMenuDescription.Layout
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
id: containersDropDown
|
id: containersDropDown
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ PageType {
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
text: SettingsController.getAppVersion()
|
text: qsTr("Software version: %1").arg(SettingsController.getAppVersion())
|
||||||
color: "#878B91"
|
color: "#878B91"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,14 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (isServerFromApi) {
|
if (ConnectionController.isConnected) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Cannot change split tunneling settings during active connection"))
|
||||||
|
root.pageEnabled = false
|
||||||
|
} else if (ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && isServerFromApi) {
|
||||||
PageController.showNotificationMessage(qsTr("Default server does not support split tunneling function"))
|
PageController.showNotificationMessage(qsTr("Default server does not support split tunneling function"))
|
||||||
|
root.pageEnabled = false
|
||||||
|
} else {
|
||||||
|
root.pageEnabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +114,7 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
checked: SitesModel.isSplitTunnelingEnabled()
|
checked: SitesModel.isTunnelingEnabled
|
||||||
onToggled: {
|
onToggled: {
|
||||||
SitesModel.toggleSplitTunneling(checked)
|
SitesModel.toggleSplitTunneling(checked)
|
||||||
selector.text = root.routeModesModel[getRouteModesModelIndex()].name
|
selector.text = root.routeModesModel[getRouteModesModelIndex()].name
|
||||||
|
|
|
@ -44,6 +44,7 @@ PageType {
|
||||||
|
|
||||||
function onClosePage() {
|
function onClosePage() {
|
||||||
tabBar.isServerInfoShow = tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsServerInfo)
|
tabBar.isServerInfoShow = tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsServerInfo)
|
||||||
|
&& tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsSplitTunneling)
|
||||||
|
|
||||||
if (tabBarStackView.depth <= 1) {
|
if (tabBarStackView.depth <= 1) {
|
||||||
return
|
return
|
||||||
|
@ -60,7 +61,7 @@ PageType {
|
||||||
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.Immediate)
|
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.Immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
tabBar.isServerInfoShow = page === PageEnum.PageSettingsServerInfo || tabBar.isServerInfoShow
|
tabBar.isServerInfoShow = page === PageEnum.PageSettingsServerInfo || PageEnum.PageSettingsSplitTunneling || tabBar.isServerInfoShow
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGoToStartPage() {
|
function onGoToStartPage() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue