app split tunneling search field (#727)

This commit is contained in:
Nethius 2024-04-06 22:29:51 +07:00 committed by GitHub
parent 7db84122f9
commit e39efb1d68
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 93 additions and 38 deletions

View file

@ -256,6 +256,16 @@ Settings::RouteMode Settings::routeMode() const
return static_cast<RouteMode>(value("Conf/routeMode", 0).toInt()); return static_cast<RouteMode>(value("Conf/routeMode", 0).toInt());
} }
bool Settings::getSitesSplitTunnelingEnabled() const
{
return value("Conf/sitesSplitTunnelingEnabled", false).toBool();
}
void Settings::setSitesSplitTunnelingEnabled(bool enabled)
{
setValue("Conf/sitesSplitTunnelingEnabled", enabled);
}
bool Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip) bool Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip)
{ {
QVariantMap sites = vpnSites(mode); QVariantMap sites = vpnSites(mode);
@ -403,6 +413,16 @@ void Settings::setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &a
m_settings.sync(); m_settings.sync();
} }
bool Settings::getAppsSplitTunnelingEnabled() const
{
return value("Conf/appsSplitTunnelingEnabled", false).toBool();
}
void Settings::setAppsSplitTunnelingEnabled(bool enabled)
{
setValue("Conf/appsSplitTunnelingEnabled", enabled);
}
ServerCredentials Settings::defaultServerCredentials() const ServerCredentials Settings::defaultServerCredentials() const
{ {
return serverCredentials(defaultServerIndex()); return serverCredentials(defaultServerIndex());

View file

@ -115,6 +115,9 @@ public:
RouteMode routeMode() const; RouteMode routeMode() const;
void setRouteMode(RouteMode mode) { setValue("Conf/routeMode", mode); } void setRouteMode(RouteMode mode) { setValue("Conf/routeMode", mode); }
bool getSitesSplitTunnelingEnabled() const;
void setSitesSplitTunnelingEnabled(bool enabled);
QVariantMap vpnSites(RouteMode mode) const QVariantMap vpnSites(RouteMode mode) const
{ {
return value("Conf/" + routeModeString(mode)).toMap(); return value("Conf/" + routeModeString(mode)).toMap();
@ -208,6 +211,9 @@ public:
QVector<InstalledAppInfo> getVpnApps(AppsRouteMode mode) const; QVector<InstalledAppInfo> getVpnApps(AppsRouteMode mode) const;
void setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &apps); void setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &apps);
bool getAppsSplitTunnelingEnabled() const;
void setAppsSplitTunnelingEnabled(bool enabled);
signals: signals:
void saveLogsChanged(bool enabled); void saveLogsChanged(bool enabled);
void screenshotsEnabledChanged(bool enabled); void screenshotsEnabledChanged(bool enabled);

View file

@ -5,14 +5,8 @@
AppSplitTunnelingModel::AppSplitTunnelingModel(std::shared_ptr<Settings> settings, QObject *parent) AppSplitTunnelingModel::AppSplitTunnelingModel(std::shared_ptr<Settings> settings, QObject *parent)
: QAbstractListModel(parent), m_settings(settings) : QAbstractListModel(parent), m_settings(settings)
{ {
auto routeMode = m_settings->getAppsRouteMode(); m_isSplitTunnelingEnabled = m_settings->getAppsSplitTunnelingEnabled();
if (routeMode == Settings::AppsRouteMode::VpnAllApps) { m_currentRouteMode = m_settings->getAppsRouteMode();
m_isSplitTunnelingEnabled = false;
m_currentRouteMode = Settings::AppsRouteMode::VpnAllExceptApps;
} else {
m_isSplitTunnelingEnabled = true;
m_currentRouteMode = routeMode;
}
m_apps = m_settings->getVpnApps(m_currentRouteMode); m_apps = m_settings->getVpnApps(m_currentRouteMode);
} }
@ -84,11 +78,7 @@ bool AppSplitTunnelingModel::isSplitTunnelingEnabled()
void AppSplitTunnelingModel::toggleSplitTunneling(bool enabled) void AppSplitTunnelingModel::toggleSplitTunneling(bool enabled)
{ {
if (enabled) { m_settings->setAppsSplitTunnelingEnabled(enabled);
setRouteMode(m_currentRouteMode);
} else {
m_settings->setAppsRouteMode(Settings::AppsRouteMode::VpnAllApps);
}
m_isSplitTunnelingEnabled = enabled; m_isSplitTunnelingEnabled = enabled;
emit splitTunnelingToggled(); emit splitTunnelingToggled();
} }

View file

@ -64,6 +64,7 @@ QVector<QPair<QString, QString>> InstalledAppsModel::getSelectedAppsInfo()
appsInfo.push_back({ appName, packageName }); appsInfo.push_back({ appName, packageName });
} }
m_selectedAppIndexes.clear();
return appsInfo; return appsInfo;
} }

View file

@ -3,14 +3,8 @@
SitesModel::SitesModel(std::shared_ptr<Settings> settings, QObject *parent) SitesModel::SitesModel(std::shared_ptr<Settings> settings, QObject *parent)
: QAbstractListModel(parent), m_settings(settings) : QAbstractListModel(parent), m_settings(settings)
{ {
auto routeMode = m_settings->routeMode(); m_isSplitTunnelingEnabled = m_settings->getSitesSplitTunnelingEnabled();
if (routeMode == Settings::RouteMode::VpnAllSites) { m_currentRouteMode = m_settings->routeMode();
m_isSplitTunnelingEnabled = false;
m_currentRouteMode = Settings::RouteMode::VpnOnlyForwardSites;
} else {
m_isSplitTunnelingEnabled = true;
m_currentRouteMode = routeMode;
}
fillSites(); fillSites();
} }
@ -107,11 +101,7 @@ bool SitesModel::isSplitTunnelingEnabled()
void SitesModel::toggleSplitTunneling(bool enabled) void SitesModel::toggleSplitTunneling(bool enabled)
{ {
if (enabled) { m_settings->setSitesSplitTunnelingEnabled(enabled);
setRouteMode(m_currentRouteMode);
} else {
m_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
}
m_isSplitTunnelingEnabled = enabled; m_isSplitTunnelingEnabled = enabled;
emit splitTunnelingToggled(); emit splitTunnelingToggled();
} }

View file

@ -59,8 +59,6 @@ DrawerType2 {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
enabled: !ServersModel.isDefaultServerDefaultContainerHasSplitTunneling || !ServersModel.getDefaultServerData("isServerFromApi")
text: qsTr("Site-based split tunneling") text: qsTr("Site-based split tunneling")
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled") descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
rightImageSource: "qrc:/images/controls/chevron-right.svg" rightImageSource: "qrc:/images/controls/chevron-right.svg"

View file

@ -5,6 +5,8 @@ import QtQuick.Layouts
import "../Controls2" import "../Controls2"
import "../Controls2/TextTypes" import "../Controls2/TextTypes"
import SortFilterProxyModel 0.2
import InstalledAppsModel 1.0 import InstalledAppsModel 1.0
DrawerType2 { DrawerType2 {
@ -34,7 +36,7 @@ DrawerType2 {
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: addButton.top anchors.bottom: searchField.top
anchors.topMargin: 16 anchors.topMargin: 16
BackButtonType { BackButtonType {
@ -66,7 +68,15 @@ DrawerType2 {
clip: true clip: true
interactive: true interactive: true
model: installedAppsModel model: SortFilterProxyModel {
id: proxyInstalledAppsModel
sourceModel: installedAppsModel
filters: RegExpFilter {
roleName: "appName"
pattern: ".*" + searchField.textField.text + ".*"
caseSensitivity: Qt.CaseInsensitive
}
}
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
id: scrollBar id: scrollBar
@ -93,7 +103,7 @@ DrawerType2 {
text: appName text: appName
onCheckedChanged: { onCheckedChanged: {
listView.model.selectedStateChanged(index, checked) installedAppsModel.selectedStateChanged(proxyInstalledAppsModel.mapToSource(index), checked)
} }
} }
@ -113,6 +123,21 @@ DrawerType2 {
} }
} }
TextFieldWithHeaderType {
id: searchField
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: addButton.top
anchors.bottomMargin: 16
anchors.rightMargin: 16
anchors.leftMargin: 16
backgroundColor: "#2C2D30"
textFieldPlaceholderText: qsTr("application name")
}
BasicButtonType { BasicButtonType {
id: addButton id: addButton
@ -127,7 +152,7 @@ DrawerType2 {
clickedFunc: function() { clickedFunc: function() {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
AppSplitTunnelingController.addApps(listView.model.getSelectedAppsInfo()) AppSplitTunnelingController.addApps(installedAppsModel.getSelectedAppsInfo())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
root.close() root.close()
} }

View file

@ -20,6 +20,17 @@ import "../Components"
PageType { PageType {
id: root id: root
property bool pageEnabled
Component.onCompleted: {
if (ConnectionController.isConnected) {
PageController.showNotificationMessage(qsTr("Cannot change split tunneling settings during active connection"))
root.pageEnabled = false
} else {
root.pageEnabled = true
}
}
QtObject { QtObject {
id: routeMode id: routeMode
property int allApps: 0 property int allApps: 0
@ -70,6 +81,8 @@ PageType {
Layout.leftMargin: 16 Layout.leftMargin: 16
headerText: qsTr("App split tunneling") headerText: qsTr("App split tunneling")
enabled: root.pageEnabled
} }
SwitcherType { SwitcherType {
@ -78,6 +91,8 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.rightMargin: 16 Layout.rightMargin: 16
enabled: root.pageEnabled
checked: AppSplitTunnelingModel.isTunnelingEnabled checked: AppSplitTunnelingModel.isTunnelingEnabled
onToggled: { onToggled: {
AppSplitTunnelingModel.toggleSplitTunneling(checked) AppSplitTunnelingModel.toggleSplitTunneling(checked)
@ -99,7 +114,7 @@ PageType {
headerText: qsTr("Mode") headerText: qsTr("Mode")
enabled: Qt.platform.os === "android" enabled: Qt.platform.os === "android" && root.pageEnabled
listView: ListViewWithRadioButtonType { listView: ListViewWithRadioButtonType {
rootWidth: root.width rootWidth: root.width
@ -139,6 +154,8 @@ PageType {
anchors.topMargin: 16 anchors.topMargin: 16
contentHeight: col.implicitHeight + addAppButton.implicitHeight + addAppButton.anchors.bottomMargin + addAppButton.anchors.topMargin contentHeight: col.implicitHeight + addAppButton.implicitHeight + addAppButton.anchors.bottomMargin + addAppButton.anchors.topMargin
enabled: root.pageEnabled
Column { Column {
id: col id: col
anchors.top: parent.top anchors.top: parent.top
@ -213,6 +230,8 @@ PageType {
RowLayout { RowLayout {
id: addAppButton id: addAppButton
enabled: root.pageEnabled
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right

View file

@ -24,9 +24,7 @@ PageType {
defaultActiveFocusItem: searchField.textField defaultActiveFocusItem: searchField.textField
property bool pageEnabled: { property bool pageEnabled
return !ConnectionController.isConnected && !isServerFromApi
}
Component.onCompleted: { Component.onCompleted: {
if (ConnectionController.isConnected) { if (ConnectionController.isConnected) {

View file

@ -301,7 +301,11 @@ void VpnConnection::appendSplitTunnelingConfig()
} }
} }
auto routeMode = m_settings->routeMode(); Settings::RouteMode routeMode = Settings::RouteMode::VpnAllSites;
if (m_settings->getSitesSplitTunnelingEnabled()) {
routeMode = m_settings->routeMode();
}
auto sites = m_settings->getVpnIps(routeMode); auto sites = m_settings->getVpnIps(routeMode);
QJsonArray sitesJsonArray; QJsonArray sitesJsonArray;
@ -318,7 +322,11 @@ void VpnConnection::appendSplitTunnelingConfig()
m_vpnConfiguration.insert(config_key::splitTunnelType, routeMode); m_vpnConfiguration.insert(config_key::splitTunnelType, routeMode);
m_vpnConfiguration.insert(config_key::splitTunnelSites, sitesJsonArray); m_vpnConfiguration.insert(config_key::splitTunnelSites, sitesJsonArray);
auto appsRouteMode = m_settings->getAppsRouteMode(); Settings::AppsRouteMode appsRouteMode = Settings::AppsRouteMode::VpnAllApps;
if (m_settings->getAppsSplitTunnelingEnabled()) {
appsRouteMode = m_settings->getAppsRouteMode();
}
auto apps = m_settings->getVpnApps(appsRouteMode); auto apps = m_settings->getVpnApps(appsRouteMode);
QJsonArray appsJsonArray; QJsonArray appsJsonArray;