diff --git a/client/ui/controllers/listViewFocusController.cpp b/client/ui/controllers/listViewFocusController.cpp
index 9fa232ca..6e91b78a 100644
--- a/client/ui/controllers/listViewFocusController.cpp
+++ b/client/ui/controllers/listViewFocusController.cpp
@@ -37,7 +37,7 @@ void ListViewFocusController::viewAtCurrentIndex() const
}
case Section::Delegate: {
QMetaObject::invokeMethod(m_listView, "positionViewAtIndex", Q_ARG(int, m_delegateIndex), // Index
- Q_ARG(int, 2)); // PositionMode (0 = Visible)
+ Q_ARG(int, 6)); // PositionMode (0 = Beginning; 1 = Center; 2 = End; 3 = Visible; 4 = Contain; 5 = SnapPosition)
break;
}
case Section::Footer: {
diff --git a/client/ui/qml/Components/HomeContainersListView.qml b/client/ui/qml/Components/HomeContainersListView.qml
index 1cbdd82d..54cb27e2 100644
--- a/client/ui/qml/Components/HomeContainersListView.qml
+++ b/client/ui/qml/Components/HomeContainersListView.qml
@@ -10,8 +10,7 @@ import ProtocolEnum 1.0
import "../Controls2"
import "../Controls2/TextTypes"
-
-ListView {
+ListViewType {
id: menuContent
property var rootWidth
@@ -21,13 +20,6 @@ ListView {
anchors.top: parent.top
anchors.bottom: parent.bottom
- clip: true
- snapMode: ListView.SnapToItem
-
- ScrollBar.vertical: ScrollBarType {}
-
- property bool isFocusable: true
-
ButtonGroup {
id: containersRadioButtonGroup
}
diff --git a/client/ui/qml/Components/HomeSplitTunnelingDrawer.qml b/client/ui/qml/Components/HomeSplitTunnelingDrawer.qml
index 097274a4..6fdb6852 100644
--- a/client/ui/qml/Components/HomeSplitTunnelingDrawer.qml
+++ b/client/ui/qml/Components/HomeSplitTunnelingDrawer.qml
@@ -1,97 +1,97 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-
-import PageEnum 1.0
-
-import "../Controls2"
-import "../Controls2/TextTypes"
-import "../Config"
-
-DrawerType2 {
- id: root
-
- property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
-
- anchors.fill: parent
- expandedHeight: parent.height * 0.9
-
- expandedStateContent: 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 {
- id: splitTunnelingSwitch
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling
-
- 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.closeTriggered()
- }
- }
-
- DividerType {
- visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling
- }
-
- LabelWithButtonType {
- id: siteBasedSplitTunnelingSwitch
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- 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.closeTriggered()
- }
- }
-
- DividerType {
- }
-
- LabelWithButtonType {
- id: appSplitTunnelingSwitch
- visible: isAppSplitTinnelingEnabled
-
- Layout.fillWidth: true
-
- text: qsTr("App-based split tunneling")
- descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
-
- clickedFunction: function() {
- PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
- root.closeTriggered()
- }
- }
-
- DividerType {
- visible: isAppSplitTinnelingEnabled
- }
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import PageEnum 1.0
+
+import "../Controls2"
+import "../Controls2/TextTypes"
+import "../Config"
+
+DrawerType2 {
+ id: root
+
+ property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
+
+ anchors.fill: parent
+ expandedHeight: parent.height * 0.9
+
+ expandedStateContent: 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 {
+ id: splitTunnelingSwitch
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+
+ visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling
+
+ 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.closeTriggered()
+ }
+ }
+
+ DividerType {
+ visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling
+ }
+
+ LabelWithButtonType {
+ id: siteBasedSplitTunnelingSwitch
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+
+ 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.closeTriggered()
+ }
+ }
+
+ DividerType {
+ }
+
+ LabelWithButtonType {
+ id: appSplitTunnelingSwitch
+ visible: isAppSplitTinnelingEnabled
+
+ Layout.fillWidth: true
+
+ text: qsTr("App-based split tunneling")
+ descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
+ rightImageSource: "qrc:/images/controls/chevron-right.svg"
+
+ clickedFunction: function() {
+ PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
+ root.closeTriggered()
+ }
+ }
+
+ DividerType {
+ visible: isAppSplitTinnelingEnabled
+ }
+ }
+}
diff --git a/client/ui/qml/Components/InstalledAppsDrawer.qml b/client/ui/qml/Components/InstalledAppsDrawer.qml
index ce8ef837..ccf8951e 100644
--- a/client/ui/qml/Components/InstalledAppsDrawer.qml
+++ b/client/ui/qml/Components/InstalledAppsDrawer.qml
@@ -57,7 +57,7 @@ DrawerType2 {
headerText: qsTr("Choose application")
}
- ListView {
+ ListViewType {
id: listView
Layout.fillWidth: true
@@ -66,11 +66,6 @@ DrawerType2 {
Layout.rightMargin: 16
Layout.leftMargin: 16
- clip: true
- interactive: true
-
- property bool isFocusable: true
-
model: SortFilterProxyModel {
id: proxyInstalledAppsModel
sourceModel: installedAppsModel
@@ -81,44 +76,35 @@ DrawerType2 {
}
}
- ScrollBar.vertical: ScrollBarType {}
-
ButtonGroup {
id: buttonGroup
}
- delegate: Item {
- implicitWidth: root.width
- implicitHeight: delegateContent.implicitHeight
+ delegate: ColumnLayout {
+ width: listView.width
- ColumnLayout {
- id: delegateContent
+ RowLayout {
+ CheckBoxType {
+ Layout.fillWidth: true
- anchors.fill: parent
-
- RowLayout {
- CheckBoxType {
- Layout.fillWidth: true
-
- text: appName
- checked: isAppSelected
- onCheckedChanged: {
- installedAppsModel.selectedStateChanged(proxyInstalledAppsModel.mapToSource(index), checked)
- }
- }
-
- Image {
- source: "image://installedAppImage/" + appIcon
-
- sourceSize.width: 24
- sourceSize.height: 24
-
- Layout.rightMargin: 48
+ text: appName
+ checked: isAppSelected
+ onCheckedChanged: {
+ installedAppsModel.selectedStateChanged(proxyInstalledAppsModel.mapToSource(index), checked)
}
}
- DividerType {}
+ Image {
+ source: "image://installedAppImage/" + appIcon
+
+ sourceSize.width: 24
+ sourceSize.height: 24
+
+ Layout.rightMargin: 48
+ }
}
+
+ DividerType {}
}
}
}
diff --git a/client/ui/qml/Components/SelectLanguageDrawer.qml b/client/ui/qml/Components/SelectLanguageDrawer.qml
index 2c026848..09829fa7 100644
--- a/client/ui/qml/Components/SelectLanguageDrawer.qml
+++ b/client/ui/qml/Components/SelectLanguageDrawer.qml
@@ -49,7 +49,7 @@ DrawerType2 {
}
}
- ListView {
+ ListViewType {
id: listView
anchors.top: backButtonLayout.bottom
@@ -57,14 +57,8 @@ DrawerType2 {
anchors.right: parent.right
anchors.bottom: parent.bottom
- property bool isFocusable: true
property int selectedIndex: LanguageModel.currentLanguageIndex
- clip: true
- reuseItems: true
-
- ScrollBar.vertical: ScrollBarType {}
-
model: LanguageModel
ButtonGroup {
diff --git a/client/ui/qml/Components/ServersListView.qml b/client/ui/qml/Components/ServersListView.qml
index d0567a8c..4417e0b2 100644
--- a/client/ui/qml/Components/ServersListView.qml
+++ b/client/ui/qml/Components/ServersListView.qml
@@ -15,7 +15,7 @@ import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
-ListView {
+ListViewType {
id: root
property int selectedIndex: ServersModel.defaultIndex
@@ -28,10 +28,6 @@ ListView {
model: ServersModel
- ScrollBar.vertical: ScrollBarType {}
-
- property bool isFocusable: true
-
Connections {
target: ServersModel
function onDefaultServerIndexChanged(serverIndex) {
@@ -39,9 +35,6 @@ ListView {
}
}
- clip: true
- reuseItems: true
-
delegate: Item {
id: menuContentDelegate
objectName: "menuContentDelegate"
diff --git a/client/ui/qml/Components/SettingsContainersListView.qml b/client/ui/qml/Components/SettingsContainersListView.qml
index 4b551cbb..ccf60917 100644
--- a/client/ui/qml/Components/SettingsContainersListView.qml
+++ b/client/ui/qml/Components/SettingsContainersListView.qml
@@ -16,75 +16,61 @@ import "../Controls2/TextTypes"
ListViewType {
id: root
- width: parent.width
- height: root.contentItem.height
+ anchors.fill: parent
- clip: true
- reuseItems: true
+ delegate: ColumnLayout {
+ width: root.width
- property bool isFocusable: false
+ LabelWithButtonType {
+ Layout.fillWidth: true
- delegate: Item {
- implicitWidth: root.width
- implicitHeight: delegateContent.implicitHeight
+ text: name
+ descriptionText: description
+ rightImageSource: isInstalled ? "qrc:/images/controls/chevron-right.svg" : "qrc:/images/controls/download.svg"
- ColumnLayout {
- id: delegateContent
+ clickedFunction: function() {
+ if (isInstalled) {
+ var containerIndex = root.model.mapToSource(index)
+ ContainersModel.setProcessedContainerIndex(containerIndex)
- anchors.fill: parent
-
- LabelWithButtonType {
- id: containerRadioButton
- implicitWidth: parent.width
-
- text: name
- descriptionText: description
- rightImageSource: isInstalled ? "qrc:/images/controls/chevron-right.svg" : "qrc:/images/controls/download.svg"
-
- clickedFunction: function() {
- if (isInstalled) {
- var containerIndex = root.model.mapToSource(index)
- ContainersModel.setProcessedContainerIndex(containerIndex)
-
- if (serviceType !== ProtocolEnum.Other) {
- if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) {
- ProtocolsModel.updateModel(config)
- PageController.goToPage(PageEnum.PageProtocolRaw)
- return
- }
- }
-
- switch (containerIndex) {
- case ContainerEnum.Ipsec: {
+ if (serviceType !== ProtocolEnum.Other) {
+ if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) {
ProtocolsModel.updateModel(config)
PageController.goToPage(PageEnum.PageProtocolRaw)
- break
+ return
}
- case ContainerEnum.Dns: {
- PageController.goToPage(PageEnum.PageServiceDnsSettings)
- break
- }
- default: {
- ProtocolsModel.updateModel(config)
- PageController.goToPage(PageEnum.PageSettingsServerProtocol)
- }
- }
-
- } else {
- ContainersModel.setProcessedContainerIndex(root.model.mapToSource(index))
- InstallController.setShouldCreateServer(false)
- PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
}
- }
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- enabled: false
+ switch (containerIndex) {
+ case ContainerEnum.Ipsec: {
+ ProtocolsModel.updateModel(config)
+ PageController.goToPage(PageEnum.PageProtocolRaw)
+ break
+ }
+ case ContainerEnum.Dns: {
+ PageController.goToPage(PageEnum.PageServiceDnsSettings)
+ break
+ }
+ default: {
+ ProtocolsModel.updateModel(config)
+ PageController.goToPage(PageEnum.PageSettingsServerProtocol)
+ }
+ }
+
+ } else {
+ ContainersModel.setProcessedContainerIndex(root.model.mapToSource(index))
+ InstallController.setShouldCreateServer(false)
+ PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
}
}
- DividerType {}
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
}
+
+ DividerType {}
}
}
diff --git a/client/ui/qml/Controls2/BasicButtonType.qml b/client/ui/qml/Controls2/BasicButtonType.qml
index b60e96cf..914fc267 100644
--- a/client/ui/qml/Controls2/BasicButtonType.qml
+++ b/client/ui/qml/Controls2/BasicButtonType.qml
@@ -1,220 +1,210 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import Qt5Compat.GraphicalEffects
-
-import Style 1.0
-
-import "TextTypes"
-
-Button {
- id: root
-
- property string hoveredColor: AmneziaStyle.color.lightGray
- property string defaultColor: AmneziaStyle.color.paleGray
- property string disabledColor: AmneziaStyle.color.charcoalGray
- property string pressedColor: AmneziaStyle.color.mutedGray
-
- property string textColor: AmneziaStyle.color.midnightBlack
-
- property string borderColor: AmneziaStyle.color.paleGray
- property string borderFocusedColor: AmneziaStyle.color.paleGray
- property int borderWidth: 0
- property int borderFocusedWidth: 1
-
- property string leftImageSource
- property string rightImageSource
- property string leftImageColor: textColor
- property bool changeLeftImageSize: true
-
- property bool squareLeftSide: false
-
- property FlickableType parentFlickable
-
- property var clickedFunc
-
- property alias buttonTextLabel: buttonText
-
- property bool isFocusable: true
-
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
- implicitHeight: 56
-
- hoverEnabled: true
-
- onFocusChanged: {
- if (root.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(this)
- }
- }
- }
-
- background: Rectangle {
- id: focusBorder
-
- color: AmneziaStyle.color.transparent
- border.color: root.activeFocus ? root.borderFocusedColor : AmneziaStyle.color.transparent
- border.width: root.activeFocus ? root.borderFocusedWidth : 0
-
- anchors.fill: parent
-
- radius: 16
-
- Rectangle {
- id: background
-
- anchors.fill: focusBorder
- anchors.margins: root.activeFocus ? 2 : 0
-
- radius: root.activeFocus ? 14 : 16
- color: {
- if (root.enabled) {
- if (root.pressed) {
- return pressedColor
- }
- return root.hovered ? hoveredColor : defaultColor
- } else {
- return disabledColor
- }
- }
- border.color: borderColor
- border.width: borderWidth
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
-
- Rectangle {
- visible: root.squareLeftSide
-
- z: 1
-
- width: parent.radius
- height: parent.radius
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- color: {
- if (root.enabled) {
- if (root.pressed) {
- return pressedColor
- }
- return root.hovered ? hoveredColor : defaultColor
- } else {
- return disabledColor
- }
- }
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
- }
- }
- }
-
- MouseArea {
- anchors.fill: focusBorder
- enabled: false
- cursorShape: Qt.PointingHandCursor
- }
-
- contentItem: Item {
- anchors.fill: focusBorder
-
- implicitWidth: content.implicitWidth
- implicitHeight: content.implicitHeight
-
- RowLayout {
- id: content
- anchors.centerIn: parent
-
- Image {
- id: leftImage
- source: root.leftImageSource
- visible: root.leftImageSource === "" ? false : true
-
- layer {
- enabled: leftImageColor !== "" ? true : false
- effect: ColorOverlay {
- color: leftImageColor
- }
- }
-
- Component.onCompleted: {
- if (root.changeLeftImageSize) {
- leftImage.Layout.preferredHeight = 20
- leftImage.Layout.preferredWidth = 20
- }
- }
- }
-
- ButtonTextType {
- id: buttonText
-
- color: root.textColor
- text: root.text
- visible: root.text === "" ? false : true
-
- horizontalAlignment: Text.AlignLeft
- 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
- }
- }
- }
- }
- }
-
- Keys.onEnterPressed: {
- if (root.clickedFunc && typeof root.clickedFunc === "function") {
- root.clickedFunc()
- }
- }
-
- Keys.onReturnPressed: {
- if (root.clickedFunc && typeof root.clickedFunc === "function") {
- root.clickedFunc()
- }
- }
-
- onClicked: {
- if (root.clickedFunc && typeof root.clickedFunc === "function") {
- root.clickedFunc()
- }
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import Qt5Compat.GraphicalEffects
+
+import Style 1.0
+
+import "TextTypes"
+
+Button {
+ id: root
+
+ property string hoveredColor: AmneziaStyle.color.lightGray
+ property string defaultColor: AmneziaStyle.color.paleGray
+ property string disabledColor: AmneziaStyle.color.charcoalGray
+ property string pressedColor: AmneziaStyle.color.mutedGray
+
+ property string textColor: AmneziaStyle.color.midnightBlack
+
+ property string borderColor: AmneziaStyle.color.paleGray
+ property string borderFocusedColor: AmneziaStyle.color.paleGray
+ property int borderWidth: 0
+ property int borderFocusedWidth: 1
+
+ property string leftImageSource
+ property string rightImageSource
+ property string leftImageColor: textColor
+ property bool changeLeftImageSize: true
+
+ property bool squareLeftSide: false
+
+ property var clickedFunc
+
+ property alias buttonTextLabel: buttonText
+
+ property bool isFocusable: true
+
+ Keys.onTabPressed: {
+ FocusController.nextKeyTabItem()
+ }
+
+ Keys.onBacktabPressed: {
+ FocusController.previousKeyTabItem()
+ }
+
+ Keys.onUpPressed: {
+ FocusController.nextKeyUpItem()
+ }
+
+ Keys.onDownPressed: {
+ FocusController.nextKeyDownItem()
+ }
+
+ Keys.onLeftPressed: {
+ FocusController.nextKeyLeftItem()
+ }
+
+ Keys.onRightPressed: {
+ FocusController.nextKeyRightItem()
+ }
+
+ implicitHeight: 56
+
+ hoverEnabled: true
+
+ background: Rectangle {
+ id: focusBorder
+
+ color: AmneziaStyle.color.transparent
+ border.color: root.activeFocus ? root.borderFocusedColor : AmneziaStyle.color.transparent
+ border.width: root.activeFocus ? root.borderFocusedWidth : 0
+
+ anchors.fill: parent
+
+ radius: 16
+
+ Rectangle {
+ id: background
+
+ anchors.fill: focusBorder
+ anchors.margins: root.activeFocus ? 2 : 0
+
+ radius: root.activeFocus ? 14 : 16
+ color: {
+ if (root.enabled) {
+ if (root.pressed) {
+ return pressedColor
+ }
+ return root.hovered ? hoveredColor : defaultColor
+ } else {
+ return disabledColor
+ }
+ }
+ border.color: borderColor
+ border.width: borderWidth
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+
+ Rectangle {
+ visible: root.squareLeftSide
+
+ z: 1
+
+ width: parent.radius
+ height: parent.radius
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ color: {
+ if (root.enabled) {
+ if (root.pressed) {
+ return pressedColor
+ }
+ return root.hovered ? hoveredColor : defaultColor
+ } else {
+ return disabledColor
+ }
+ }
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: focusBorder
+ enabled: false
+ cursorShape: Qt.PointingHandCursor
+ }
+
+ contentItem: Item {
+ anchors.fill: focusBorder
+
+ implicitWidth: content.implicitWidth
+ implicitHeight: content.implicitHeight
+
+ RowLayout {
+ id: content
+ anchors.centerIn: parent
+
+ Image {
+ id: leftImage
+ source: root.leftImageSource
+ visible: root.leftImageSource === "" ? false : true
+
+ layer {
+ enabled: leftImageColor !== "" ? true : false
+ effect: ColorOverlay {
+ color: leftImageColor
+ }
+ }
+
+ Component.onCompleted: {
+ if (root.changeLeftImageSize) {
+ leftImage.Layout.preferredHeight = 20
+ leftImage.Layout.preferredWidth = 20
+ }
+ }
+ }
+
+ ButtonTextType {
+ id: buttonText
+
+ color: root.textColor
+ text: root.text
+ visible: root.text === "" ? false : true
+
+ horizontalAlignment: Text.AlignLeft
+ 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
+ }
+ }
+ }
+ }
+ }
+
+ Keys.onEnterPressed: {
+ if (root.clickedFunc && typeof root.clickedFunc === "function") {
+ root.clickedFunc()
+ }
+ }
+
+ Keys.onReturnPressed: {
+ if (root.clickedFunc && typeof root.clickedFunc === "function") {
+ root.clickedFunc()
+ }
+ }
+
+ onClicked: {
+ if (root.clickedFunc && typeof root.clickedFunc === "function") {
+ root.clickedFunc()
+ }
+ }
+}
diff --git a/client/ui/qml/Controls2/CardWithIconsType.qml b/client/ui/qml/Controls2/CardWithIconsType.qml
index 4277d735..02d033d2 100644
--- a/client/ui/qml/Controls2/CardWithIconsType.qml
+++ b/client/ui/qml/Controls2/CardWithIconsType.qml
@@ -1,203 +1,185 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-
-import Style 1.0
-
-import "TextTypes"
-
-Button {
- id: root
-
- property string headerText
- property string bodyText
- property string footerText
-
- property string hoveredColor: AmneziaStyle.color.slateGray
- property string defaultColor: AmneziaStyle.color.onyxBlack
-
- property string textColor: AmneziaStyle.color.midnightBlack
-
- property string rightImageSource
- property string rightImageColor: AmneziaStyle.color.paleGray
-
- property string leftImageSource
-
- property real textOpacity: 1.0
-
- property alias focusItem: rightImage
-
- property FlickableType parentFlickable
-
- hoverEnabled: true
-
- background: Rectangle {
- id: backgroundRect
-
- anchors.fill: parent
- radius: 16
-
- color: defaultColor
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
- }
-
- function ensureVisible(item) {
- if (item.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(root)
- }
- }
- }
-
- onFocusChanged: {
- ensureVisible(root)
- }
-
- focusItem.onFocusChanged: {
- root.ensureVisible(focusItem)
- }
-
- contentItem: Item {
- anchors.left: parent.left
- anchors.right: parent.right
-
- implicitHeight: content.implicitHeight
-
- RowLayout {
- id: content
-
- anchors.fill: parent
-
- Image {
- id: leftImage
- source: leftImageSource
-
- visible: leftImageSource !== ""
-
- Layout.alignment: Qt.AlignLeft | Qt.AlignTop
- Layout.topMargin: 24
- Layout.bottomMargin: 24
- Layout.leftMargin: 24
- }
-
- ColumnLayout {
-
- ListItemTitleType {
- text: root.headerText
- visible: text !== ""
-
- Layout.fillWidth: true
- Layout.rightMargin: 16
- Layout.leftMargin: 16
- Layout.topMargin: 16
- Layout.bottomMargin: root.bodyText !== "" ? 0 : 16
-
- opacity: root.textOpacity
- }
-
- CaptionTextType {
- text: root.bodyText
- visible: text !== ""
-
- color: AmneziaStyle.color.mutedGray
- textFormat: Text.RichText
-
- Layout.fillWidth: true
- Layout.rightMargin: 16
- Layout.leftMargin: 16
- Layout.bottomMargin: root.footerText !== "" ? 0 : 16
-
- opacity: root.textOpacity
- }
-
- ButtonTextType {
- text: root.footerText
- visible: text !== ""
-
- color: AmneziaStyle.color.mutedGray
-
- Layout.fillWidth: true
- Layout.rightMargin: 16
- Layout.leftMargin: 16
- Layout.topMargin: 16
- Layout.bottomMargin: 16
-
- opacity: root.textOpacity
- }
- }
-
- ImageButtonType {
- id: rightImage
-
- implicitWidth: 40
- implicitHeight: 40
-
- hoverEnabled: false
- image: rightImageSource
- imageColor: rightImageColor
- visible: rightImageSource ? true : false
-
- Layout.alignment: Qt.AlignRight | Qt.AlignTop
- Layout.topMargin: 16
- Layout.bottomMargin: 16
- Layout.rightMargin: 16
-
- Rectangle {
- id: rightImageBackground
-
- anchors.fill: parent
- radius: 12
- color: "transparent"
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
- }
-
- onClicked: {
- root.clicked()
- }
- }
- }
- }
-
- MouseArea {
- anchors.fill: parent
-
- cursorShape: Qt.PointingHandCursor
- hoverEnabled: true
- enabled: root.enabled
-
- onEntered: {
- backgroundRect.color = root.hoveredColor
-
- if (rightImageSource) {
- rightImageBackground.color = rightImage.hoveredColor
- }
- root.textOpacity = 0.8
- }
-
- onExited: {
- backgroundRect.color = root.defaultColor
-
- if (rightImageSource) {
- rightImageBackground.color = rightImage.defaultColor
- }
- root.textOpacity = 1
- }
-
- onPressedChanged: {
- if (rightImageSource) {
- rightImageBackground.color = pressed ? rightImage.pressedColor : entered ? rightImage.hoveredColor : rightImage.defaultColor
- }
- root.textOpacity = 0.7
- }
-
- onClicked: {
- root.clicked()
- }
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import Style 1.0
+
+import "TextTypes"
+
+Button {
+ id: root
+
+ property string headerText
+ property string bodyText
+ property string footerText
+
+ property string hoveredColor: AmneziaStyle.color.slateGray
+ property string defaultColor: AmneziaStyle.color.onyxBlack
+
+ property string textColor: AmneziaStyle.color.midnightBlack
+
+ property string rightImageSource
+ property string rightImageColor: AmneziaStyle.color.paleGray
+
+ property string leftImageSource
+
+ property real textOpacity: 1.0
+
+ property alias focusItem: rightImage
+
+ hoverEnabled: true
+
+ background: Rectangle {
+ id: backgroundRect
+
+ anchors.fill: parent
+ radius: 16
+
+ color: defaultColor
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+
+ contentItem: Item {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ implicitHeight: content.implicitHeight
+
+ RowLayout {
+ id: content
+
+ anchors.fill: parent
+
+ Image {
+ id: leftImage
+ source: leftImageSource
+
+ visible: leftImageSource !== ""
+
+ Layout.alignment: Qt.AlignLeft | Qt.AlignTop
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 24
+ }
+
+ ColumnLayout {
+
+ ListItemTitleType {
+ text: root.headerText
+ visible: text !== ""
+
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.topMargin: 16
+ Layout.bottomMargin: root.bodyText !== "" ? 0 : 16
+
+ opacity: root.textOpacity
+ }
+
+ CaptionTextType {
+ text: root.bodyText
+ visible: text !== ""
+
+ color: AmneziaStyle.color.mutedGray
+ textFormat: Text.RichText
+
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.bottomMargin: root.footerText !== "" ? 0 : 16
+
+ opacity: root.textOpacity
+ }
+
+ ButtonTextType {
+ text: root.footerText
+ visible: text !== ""
+
+ color: AmneziaStyle.color.mutedGray
+
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.topMargin: 16
+ Layout.bottomMargin: 16
+
+ opacity: root.textOpacity
+ }
+ }
+
+ ImageButtonType {
+ id: rightImage
+
+ implicitWidth: 40
+ implicitHeight: 40
+
+ hoverEnabled: false
+ image: rightImageSource
+ imageColor: rightImageColor
+ visible: rightImageSource ? true : false
+
+ Layout.alignment: Qt.AlignRight | Qt.AlignTop
+ Layout.topMargin: 16
+ Layout.bottomMargin: 16
+ Layout.rightMargin: 16
+
+ Rectangle {
+ id: rightImageBackground
+
+ anchors.fill: parent
+ radius: 12
+ color: "transparent"
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+
+ onClicked: {
+ root.clicked()
+ }
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+
+ cursorShape: Qt.PointingHandCursor
+ hoverEnabled: true
+ enabled: root.enabled
+
+ onEntered: {
+ backgroundRect.color = root.hoveredColor
+
+ if (rightImageSource) {
+ rightImageBackground.color = rightImage.hoveredColor
+ }
+ root.textOpacity = 0.8
+ }
+
+ onExited: {
+ backgroundRect.color = root.defaultColor
+
+ if (rightImageSource) {
+ rightImageBackground.color = rightImage.defaultColor
+ }
+ root.textOpacity = 1
+ }
+
+ onPressedChanged: {
+ if (rightImageSource) {
+ rightImageBackground.color = pressed ? rightImage.pressedColor : entered ? rightImage.hoveredColor : rightImage.defaultColor
+ }
+ root.textOpacity = 0.7
+ }
+
+ onClicked: {
+ root.clicked()
+ }
+ }
+}
diff --git a/client/ui/qml/Controls2/CheckBoxType.qml b/client/ui/qml/Controls2/CheckBoxType.qml
index a26a68f1..451fe01d 100644
--- a/client/ui/qml/Controls2/CheckBoxType.qml
+++ b/client/ui/qml/Controls2/CheckBoxType.qml
@@ -1,170 +1,187 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import Qt5Compat.GraphicalEffects
-
-import Style 1.0
-
-import "TextTypes"
-
-CheckBox {
- id: root
-
- property string descriptionText
- property string descriptionTextColor: AmneziaStyle.color.mutedGray
- property string descriptionTextDisabledColor: AmneziaStyle.color.charcoalGray
-
- property string textColor: AmneziaStyle.color.paleGray
- property string textDisabledColor: AmneziaStyle.color.mutedGray
-
- property string hoveredColor: AmneziaStyle.color.barelyTranslucentWhite
- property string defaultColor: AmneziaStyle.color.transparent
- property string pressedColor: AmneziaStyle.color.barelyTranslucentWhite
-
- property string defaultBorderColor: AmneziaStyle.color.paleGray
- property string checkedBorderColor: AmneziaStyle.color.goldenApricot
- property string checkedBorderDisabledColor: AmneziaStyle.color.deepBrown
-
- property string borderFocusedColor: AmneziaStyle.color.paleGray
-
- property string checkedImageColor: AmneziaStyle.color.goldenApricot
- property string pressedImageColor: AmneziaStyle.color.burntOrange
- property string defaultImageColor: AmneziaStyle.color.transparent
- property string checkedDisabledImageColor: AmneziaStyle.color.mutedBrown
-
- property string imageSource: "qrc:/images/controls/check.svg"
-
- property var parentFlickable
- onFocusChanged: {
- if (root.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(root)
- }
- }
- }
-
- hoverEnabled: enabled ? true : false
- focusPolicy: Qt.NoFocus
-
- background: Rectangle {
- color: AmneziaStyle.color.transparent
- border.color: root.focus ? borderFocusedColor : AmneziaStyle.color.transparent
- border.width: 1
- radius: 16
- }
-
- indicator: Rectangle {
- id: background
-
- anchors.verticalCenter: parent.verticalCenter
-
- implicitWidth: 56
- implicitHeight: 56
- radius: 16
-
- color: {
- if (root.hovered) {
- return hoveredColor
- }
- return defaultColor
- }
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
-
- Rectangle {
- id: imageBorder
-
- anchors.centerIn: parent
- width: 24
- height: 24
- color: AmneziaStyle.color.transparent
- border.color: root.checked ?
- (root.enabled ?
- checkedBorderColor :
- checkedBorderDisabledColor) :
- defaultBorderColor
- border.width: 1
- radius: 4
-
- Image {
- anchors.centerIn: parent
-
- source: root.pressed ? imageSource : root.checked ? imageSource : ""
- layer {
- enabled: true
- effect: ColorOverlay {
- color: {
- if (root.pressed) {
- return root.pressedImageColor
- } else if (root.checked) {
- if (root.enabled) {
- return root.checkedImageColor
- } else {
- return root.checkedDisabledImageColor
- }
- } else {
- return root.defaultImageColor
- }
- }
- }
- }
- }
- }
- }
-
- contentItem: Item {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.leftMargin: 8 + background.width
-
- implicitHeight: content.implicitHeight
-
- ColumnLayout {
- id: content
-
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
-
- spacing: 4
-
- ListItemTitleType {
- Layout.fillWidth: true
-
- text: root.text
- color: root.enabled ? root.textColor : root.textDisabledColor
- }
-
- CaptionTextType {
- id: description
-
- Layout.fillWidth: true
-
- text: root.descriptionText
- color: root.enabled ? root.descriptionTextColor : root.descriptionTextDisabledColor
-
- visible: root.descriptionText !== ""
- }
- }
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- enabled: false
- }
-
-
- Keys.onEnterPressed: {
- root.checked = !root.checked
- }
-
- Keys.onReturnPressed: {
- root.checked = !root.checked
- }
-
-}
-
-
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import Qt5Compat.GraphicalEffects
+
+import Style 1.0
+
+import "TextTypes"
+
+CheckBox {
+ id: root
+
+ property string descriptionText
+ property string descriptionTextColor: AmneziaStyle.color.mutedGray
+ property string descriptionTextDisabledColor: AmneziaStyle.color.charcoalGray
+
+ property string textColor: AmneziaStyle.color.paleGray
+ property string textDisabledColor: AmneziaStyle.color.mutedGray
+
+ property string hoveredColor: AmneziaStyle.color.barelyTranslucentWhite
+ property string defaultColor: AmneziaStyle.color.transparent
+ property string pressedColor: AmneziaStyle.color.barelyTranslucentWhite
+
+ property string defaultBorderColor: AmneziaStyle.color.paleGray
+ property string checkedBorderColor: AmneziaStyle.color.goldenApricot
+ property string checkedBorderDisabledColor: AmneziaStyle.color.deepBrown
+
+ property string borderFocusedColor: AmneziaStyle.color.paleGray
+
+ property string checkedImageColor: AmneziaStyle.color.goldenApricot
+ property string pressedImageColor: AmneziaStyle.color.burntOrange
+ property string defaultImageColor: AmneziaStyle.color.transparent
+ property string checkedDisabledImageColor: AmneziaStyle.color.mutedBrown
+
+ property string imageSource: "qrc:/images/controls/check.svg"
+
+ property bool isFocusable: true
+
+ Keys.onTabPressed: {
+ FocusController.nextKeyTabItem()
+ }
+
+ Keys.onBacktabPressed: {
+ FocusController.previousKeyTabItem()
+ }
+
+ Keys.onUpPressed: {
+ FocusController.nextKeyUpItem()
+ }
+
+ Keys.onDownPressed: {
+ FocusController.nextKeyDownItem()
+ }
+
+ Keys.onLeftPressed: {
+ FocusController.nextKeyLeftItem()
+ }
+
+ Keys.onRightPressed: {
+ FocusController.nextKeyRightItem()
+ }
+
+ hoverEnabled: enabled ? true : false
+ focusPolicy: Qt.NoFocus
+
+ background: Rectangle {
+ color: AmneziaStyle.color.transparent
+ border.color: root.focus ? borderFocusedColor : AmneziaStyle.color.transparent
+ border.width: 1
+ radius: 16
+ }
+
+ indicator: Rectangle {
+ id: background
+
+ anchors.verticalCenter: parent.verticalCenter
+
+ implicitWidth: 56
+ implicitHeight: 56
+ radius: 16
+
+ color: {
+ if (root.hovered) {
+ return hoveredColor
+ }
+ return defaultColor
+ }
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+
+ Rectangle {
+ id: imageBorder
+
+ anchors.centerIn: parent
+ width: 24
+ height: 24
+ color: AmneziaStyle.color.transparent
+ border.color: root.checked ?
+ (root.enabled ?
+ checkedBorderColor :
+ checkedBorderDisabledColor) :
+ defaultBorderColor
+ border.width: 1
+ radius: 4
+
+ Image {
+ anchors.centerIn: parent
+
+ source: root.pressed ? imageSource : root.checked ? imageSource : ""
+ layer {
+ enabled: true
+ effect: ColorOverlay {
+ color: {
+ if (root.pressed) {
+ return root.pressedImageColor
+ } else if (root.checked) {
+ if (root.enabled) {
+ return root.checkedImageColor
+ } else {
+ return root.checkedDisabledImageColor
+ }
+ } else {
+ return root.defaultImageColor
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ contentItem: Item {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: 8 + background.width
+
+ implicitHeight: content.implicitHeight
+
+ ColumnLayout {
+ id: content
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+
+ spacing: 4
+
+ ListItemTitleType {
+ Layout.fillWidth: true
+
+ text: root.text
+ color: root.enabled ? root.textColor : root.textDisabledColor
+ }
+
+ CaptionTextType {
+ id: description
+
+ Layout.fillWidth: true
+
+ text: root.descriptionText
+ color: root.enabled ? root.descriptionTextColor : root.descriptionTextDisabledColor
+
+ visible: root.descriptionText !== ""
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
+
+
+ Keys.onEnterPressed: {
+ root.checked = !root.checked
+ }
+
+ Keys.onReturnPressed: {
+ root.checked = !root.checked
+ }
+
+}
+
+
diff --git a/client/ui/qml/Controls2/LabelWithButtonType.qml b/client/ui/qml/Controls2/LabelWithButtonType.qml
index 087415f7..56d721b9 100644
--- a/client/ui/qml/Controls2/LabelWithButtonType.qml
+++ b/client/ui/qml/Controls2/LabelWithButtonType.qml
@@ -1,328 +1,309 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-
-import Style 1.0
-
-import "TextTypes"
-
-Item {
- id: root
-
- property string text
- property int textMaximumLineCount: 2
- property int textElide: Qt.ElideRight
-
- property string descriptionText
-
- property var clickedFunction
-
- property string buttonImageSource
- property string rightImageSource
- property string leftImageSource
- property bool isLeftImageHoverEnabled: true
- property bool isSmallLeftImage: false
-
- property alias rightButton: rightImage
- property alias eyeButton: eyeImage
- property FlickableType parentFlickable
-
- property string textColor: AmneziaStyle.color.paleGray
- property string textDisabledColor: AmneziaStyle.color.mutedGray
- property string descriptionColor: AmneziaStyle.color.mutedGray
- property string descriptionDisabledColor: AmneziaStyle.color.charcoalGray
- property real textOpacity: 1.0
-
- property string borderFocusedColor: AmneziaStyle.color.paleGray
- property int borderFocusedWidth: 1
-
- property string rightImageColor: AmneziaStyle.color.paleGray
-
- property bool descriptionOnTop: false
- property bool hideDescription: true
-
- property bool isFocusable: !(eyeImage.visible || rightImage.visible) // TODO: this component already has focusable items
-
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
- implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
- implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
-
- onFocusChanged: {
- if (root.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(root)
- }
- }
- }
-
- Connections {
- target: rightImage
- function onFocusChanged() {
- if (rightImage.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(root)
- }
- }
- }
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- hoverEnabled: root.enabled
-
- onEntered: {
- if (rightImageSource) {
- rightImageBackground.color = rightImage.hoveredColor
- } else if (leftImageSource) {
- leftImageBackground.color = rightImage.hoveredColor
- }
- root.textOpacity = 0.8
- }
-
- onExited: {
- if (rightImageSource) {
- rightImageBackground.color = rightImage.defaultColor
- } else if (leftImageSource) {
- leftImageBackground.color = rightImage.defaultColor
- }
- root.textOpacity = 1
- }
-
- onPressedChanged: {
- if (rightImageSource) {
- rightImageBackground.color = pressed ? rightImage.pressedColor : entered ? rightImage.hoveredColor : rightImage.defaultColor
- } else if (leftImageSource) {
- leftImageBackground.color = pressed ? rightImage.pressedColor : entered ? rightImage.hoveredColor : rightImage.defaultColor
- }
- root.textOpacity = 0.7
- }
-
- onClicked: {
- if (clickedFunction && typeof clickedFunction === "function") {
- clickedFunction()
- }
- }
- }
-
- RowLayout {
- id: content
- anchors.fill: parent
- anchors.leftMargin: 16
- anchors.rightMargin: 16
- anchors.topMargin: 16
- anchors.bottomMargin: 16
-
- Rectangle {
- id: leftImageBackground
-
- visible: leftImageSource ? true : false
-
- Layout.preferredHeight: (rightImageSource || !isLeftImageHoverEnabled || isSmallLeftImage) ? 40 : 56
- Layout.preferredWidth: (rightImageSource || !isLeftImageHoverEnabled || isSmallLeftImage)? 40 : 56
- Layout.rightMargin: isSmallLeftImage ? 8 : (rightImageSource || !isLeftImageHoverEnabled) ? 16 : 0
-
- radius: 12
- color: AmneziaStyle.color.transparent
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
-
- Image {
- id: leftImage
-
- anchors.centerIn: parent
- source: leftImageSource
- }
- }
-
- ColumnLayout {
- property real textLineHeight: 21.6
- property real descriptionTextLineHeight: 16
-
- property int textPixelSize: 18
- property int descriptionTextSize: 13
-
- ListItemTitleType {
- text: root.text
- color: {
- if (root.enabled) {
- return root.descriptionOnTop ? root.descriptionColor : root.textColor
- } else {
- return root.descriptionOnTop ? root.descriptionDisabledColor : root.textDisabledColor
- }
- }
-
- maximumLineCount: root.textMaximumLineCount
- elide: root.textElide
-
- opacity: root.textOpacity
-
- Layout.fillWidth: true
-
- lineHeight: root.descriptionOnTop ? parent.descriptionTextLineHeight : parent.textLineHeight
- font.pixelSize: root.descriptionOnTop ? parent.descriptionTextSize : parent.textPixelSize
- font.letterSpacing: root.descriptionOnTop ? 0.02 : 0
-
- horizontalAlignment: Text.AlignLeft
- verticalAlignment: Text.AlignVCenter
-
- Behavior on opacity {
- PropertyAnimation { duration: 200 }
- }
- }
-
-
- CaptionTextType {
- id: description
-
- text: (eyeImage.visible && hideDescription) ? replaceWithAsterisks(root.descriptionText) : root.descriptionText
- color: {
- if (root.enabled) {
- return root.descriptionOnTop ? root.textColor : root.descriptionColor
- } else {
- return root.descriptionOnTop ? root.textDisabledColor : root.descriptionDisabledColor
- }
- }
-
- opacity: root.textOpacity
-
- visible: root.descriptionText !== ""
-
- Layout.fillWidth: true
-
- lineHeight: root.descriptionOnTop ? parent.textLineHeight : parent.descriptionTextLineHeight
- font.pixelSize: root.descriptionOnTop ? parent.textPixelSize : parent.descriptionTextSize
- font.letterSpacing: root.descriptionOnTop ? 0 : 0.02
-
- horizontalAlignment: Text.AlignLeft
- verticalAlignment: Text.AlignVCenter
-
- Behavior on opacity {
- PropertyAnimation { duration: 200 }
- }
-
- function replaceWithAsterisks(input) {
- return '*'.repeat(input.length)
- }
- }
- }
-
- ImageButtonType {
- id: eyeImage
- visible: buttonImageSource !== ""
-
- implicitWidth: 40
- implicitHeight: 40
-
- hoverEnabled: true
- image: buttonImageSource
- imageColor: rightImageColor
-
- Layout.alignment: Qt.AlignRight
-
- Rectangle {
- id: eyeImageBackground
- anchors.fill: parent
- radius: 12
- color: AmneziaStyle.color.transparent
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
- }
-
- onClicked: {
- hideDescription = !hideDescription
- }
-
- Keys.onEnterPressed: {
- clicked()
- }
-
- Keys.onReturnPressed: {
- clicked()
- }
- }
-
- ImageButtonType {
- id: rightImage
-
- implicitWidth: 40
- implicitHeight: 40
-
- hoverEnabled: false
- image: rightImageSource
- imageColor: rightImageColor
- visible: rightImageSource ? true : false
-
- Layout.alignment: Qt.AlignRight
-
- Rectangle {
- id: rightImageBackground
- anchors.fill: parent
- radius: 12
- color: AmneziaStyle.color.transparent
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
- }
- onClicked: {
- if (clickedFunction && typeof clickedFunction === "function") {
- clickedFunction()
- }
- }
- }
- }
-
- Rectangle {
- id: background
- anchors.fill: root
- color: AmneziaStyle.color.transparent
-
- border.color: root.activeFocus ? root.borderFocusedColor : AmneziaStyle.color.transparent
- border.width: root.activeFocus ? root.borderFocusedWidth : 0
-
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
- }
-
- Keys.onEnterPressed: {
- if (clickedFunction && typeof clickedFunction === "function") {
- clickedFunction()
- }
- }
-
- Keys.onReturnPressed: {
- if (clickedFunction && typeof clickedFunction === "function") {
- clickedFunction()
- }
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import Style 1.0
+
+import "TextTypes"
+
+Item {
+ id: root
+
+ // property alias focusObjectName: eyeImage.objectName
+ property string text
+ property int textMaximumLineCount: 2
+ property int textElide: Qt.ElideRight
+
+ property string descriptionText
+
+ property var clickedFunction
+
+ property string buttonImageSource
+ property string rightImageSource
+ property string leftImageSource
+ property bool isLeftImageHoverEnabled: true
+ property bool isSmallLeftImage: false
+
+ property alias rightButton: rightImage
+ property alias eyeButton: eyeImage
+
+ property string textColor: AmneziaStyle.color.paleGray
+ property string textDisabledColor: AmneziaStyle.color.mutedGray
+ property string descriptionColor: AmneziaStyle.color.mutedGray
+ property string descriptionDisabledColor: AmneziaStyle.color.charcoalGray
+ property real textOpacity: 1.0
+
+ property string borderFocusedColor: AmneziaStyle.color.paleGray
+ property int borderFocusedWidth: 1
+
+ property string rightImageColor: AmneziaStyle.color.paleGray
+
+ property bool descriptionOnTop: false
+ property bool hideDescription: true
+
+ property bool isFocusable: !(eyeImage.visible || rightImage.visible) // TODO: this component already has focusable items
+
+ Keys.onTabPressed: {
+ FocusController.nextKeyTabItem()
+ }
+
+ Keys.onBacktabPressed: {
+ FocusController.previousKeyTabItem()
+ }
+
+ Keys.onUpPressed: {
+ FocusController.nextKeyUpItem()
+ }
+
+ Keys.onDownPressed: {
+ FocusController.nextKeyDownItem()
+ }
+
+ Keys.onLeftPressed: {
+ FocusController.nextKeyLeftItem()
+ }
+
+ Keys.onRightPressed: {
+ FocusController.nextKeyRightItem()
+ }
+
+ implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
+ implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ hoverEnabled: root.enabled
+
+ onEntered: {
+ if (rightImageSource) {
+ rightImageBackground.color = rightImage.hoveredColor
+ } else if (leftImageSource) {
+ leftImageBackground.color = rightImage.hoveredColor
+ }
+ root.textOpacity = 0.8
+ }
+
+ onExited: {
+ if (rightImageSource) {
+ rightImageBackground.color = rightImage.defaultColor
+ } else if (leftImageSource) {
+ leftImageBackground.color = rightImage.defaultColor
+ }
+ root.textOpacity = 1
+ }
+
+ onPressedChanged: {
+ if (rightImageSource) {
+ rightImageBackground.color = pressed ? rightImage.pressedColor : entered ? rightImage.hoveredColor : rightImage.defaultColor
+ } else if (leftImageSource) {
+ leftImageBackground.color = pressed ? rightImage.pressedColor : entered ? rightImage.hoveredColor : rightImage.defaultColor
+ }
+ root.textOpacity = 0.7
+ }
+
+ onClicked: {
+ if (clickedFunction && typeof clickedFunction === "function") {
+ clickedFunction()
+ }
+ }
+ }
+
+ RowLayout {
+ id: content
+ anchors.fill: parent
+ anchors.leftMargin: 16
+ anchors.rightMargin: 16
+ anchors.topMargin: 16
+ anchors.bottomMargin: 16
+
+ Rectangle {
+ id: leftImageBackground
+
+ visible: leftImageSource ? true : false
+
+ Layout.preferredHeight: (rightImageSource || !isLeftImageHoverEnabled || isSmallLeftImage) ? 40 : 56
+ Layout.preferredWidth: (rightImageSource || !isLeftImageHoverEnabled || isSmallLeftImage)? 40 : 56
+ Layout.rightMargin: isSmallLeftImage ? 8 : (rightImageSource || !isLeftImageHoverEnabled) ? 16 : 0
+
+ radius: 12
+ color: AmneziaStyle.color.transparent
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+
+ Image {
+ id: leftImage
+
+ anchors.centerIn: parent
+ source: leftImageSource
+ }
+ }
+
+ ColumnLayout {
+ property real textLineHeight: 21.6
+ property real descriptionTextLineHeight: 16
+
+ property int textPixelSize: 18
+ property int descriptionTextSize: 13
+
+ ListItemTitleType {
+ text: root.text
+ color: {
+ if (root.enabled) {
+ return root.descriptionOnTop ? root.descriptionColor : root.textColor
+ } else {
+ return root.descriptionOnTop ? root.descriptionDisabledColor : root.textDisabledColor
+ }
+ }
+
+ maximumLineCount: root.textMaximumLineCount
+ elide: root.textElide
+
+ opacity: root.textOpacity
+
+ Layout.fillWidth: true
+
+ lineHeight: root.descriptionOnTop ? parent.descriptionTextLineHeight : parent.textLineHeight
+ font.pixelSize: root.descriptionOnTop ? parent.descriptionTextSize : parent.textPixelSize
+ font.letterSpacing: root.descriptionOnTop ? 0.02 : 0
+
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+
+ Behavior on opacity {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+
+
+ CaptionTextType {
+ id: description
+
+ text: (eyeImage.visible && hideDescription) ? replaceWithAsterisks(root.descriptionText) : root.descriptionText
+ color: {
+ if (root.enabled) {
+ return root.descriptionOnTop ? root.textColor : root.descriptionColor
+ } else {
+ return root.descriptionOnTop ? root.textDisabledColor : root.descriptionDisabledColor
+ }
+ }
+
+ opacity: root.textOpacity
+
+ visible: root.descriptionText !== ""
+
+ Layout.fillWidth: true
+
+ lineHeight: root.descriptionOnTop ? parent.textLineHeight : parent.descriptionTextLineHeight
+ font.pixelSize: root.descriptionOnTop ? parent.textPixelSize : parent.descriptionTextSize
+ font.letterSpacing: root.descriptionOnTop ? 0 : 0.02
+
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+
+ Behavior on opacity {
+ PropertyAnimation { duration: 200 }
+ }
+
+ function replaceWithAsterisks(input) {
+ return '*'.repeat(input.length)
+ }
+ }
+ }
+
+ ImageButtonType {
+ id: eyeImage
+ visible: buttonImageSource !== ""
+
+ implicitWidth: 40
+ implicitHeight: 40
+
+ hoverEnabled: true
+ image: buttonImageSource
+ imageColor: rightImageColor
+
+ Layout.alignment: Qt.AlignRight
+
+ Rectangle {
+ id: eyeImageBackground
+ anchors.fill: parent
+ radius: 12
+ color: AmneziaStyle.color.transparent
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+
+ onClicked: {
+ hideDescription = !hideDescription
+ }
+
+ Keys.onEnterPressed: {
+ clicked()
+ }
+
+ Keys.onReturnPressed: {
+ clicked()
+ }
+ }
+
+ ImageButtonType {
+ id: rightImage
+
+ implicitWidth: 40
+ implicitHeight: 40
+
+ hoverEnabled: false
+ image: rightImageSource
+ imageColor: rightImageColor
+ visible: rightImageSource ? true : false
+
+ Layout.alignment: Qt.AlignRight
+
+ Rectangle {
+ id: rightImageBackground
+ anchors.fill: parent
+ radius: 12
+ color: AmneziaStyle.color.transparent
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+ onClicked: {
+ if (clickedFunction && typeof clickedFunction === "function") {
+ clickedFunction()
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: background
+ anchors.fill: root
+ color: AmneziaStyle.color.transparent
+
+ border.color: root.activeFocus ? root.borderFocusedColor : AmneziaStyle.color.transparent
+ border.width: root.activeFocus ? root.borderFocusedWidth : 0
+
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+
+ Keys.onEnterPressed: {
+ if (clickedFunction && typeof clickedFunction === "function") {
+ clickedFunction()
+ }
+ }
+
+ Keys.onReturnPressed: {
+ if (clickedFunction && typeof clickedFunction === "function") {
+ clickedFunction()
+ }
+ }
+}
diff --git a/client/ui/qml/Controls2/ListViewType.qml b/client/ui/qml/Controls2/ListViewType.qml
index 0de43d77..8d067537 100644
--- a/client/ui/qml/Controls2/ListViewType.qml
+++ b/client/ui/qml/Controls2/ListViewType.qml
@@ -6,33 +6,16 @@ ListView {
property bool isFocusable: true
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
ScrollBar.vertical: ScrollBarType {}
clip: true
reuseItems: true
- snapMode: ListView.SnapToItem
+
+ function findChildWithObjectName(items, name) {
+ for (var i = 0; i < items.length; ++i) {
+ if (items[i].objectName === name)
+ return items[i];
+ }
+ return null;
+ }
}
diff --git a/client/ui/qml/Controls2/ListViewWithRadioButtonType.qml b/client/ui/qml/Controls2/ListViewWithRadioButtonType.qml
index bd7ca32e..abd4da3e 100644
--- a/client/ui/qml/Controls2/ListViewWithRadioButtonType.qml
+++ b/client/ui/qml/Controls2/ListViewWithRadioButtonType.qml
@@ -6,7 +6,7 @@ import Style 1.0
import "TextTypes"
-ListView {
+ListViewType {
id: root
property var rootWidth
@@ -25,13 +25,6 @@ ListView {
width: rootWidth
height: root.contentItem.height
- clip: true
- reuseItems: true
-
- property bool isFocusable: true
-
- ScrollBar.vertical: ScrollBarType {}
-
ButtonGroup {
id: buttonGroup
}
diff --git a/client/ui/qml/Controls2/SwitcherType.qml b/client/ui/qml/Controls2/SwitcherType.qml
index 0651390f..db9ef755 100644
--- a/client/ui/qml/Controls2/SwitcherType.qml
+++ b/client/ui/qml/Controls2/SwitcherType.qml
@@ -1,172 +1,162 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-
-import Style 1.0
-
-import "TextTypes"
-
-Switch {
- id: root
-
- property alias descriptionText: description.text
- property string descriptionTextColor: AmneziaStyle.color.mutedGray
- property string descriptionTextDisabledColor: AmneziaStyle.color.charcoalGray
-
- property string textColor: AmneziaStyle.color.paleGray
- property string textDisabledColor: AmneziaStyle.color.mutedGray
-
- property string checkedIndicatorColor: AmneziaStyle.color.richBrown
- property string defaultIndicatorColor: AmneziaStyle.color.transparent
- property string checkedDisabledIndicatorColor: AmneziaStyle.color.deepBrown
-
- property string borderFocusedColor: AmneziaStyle.color.paleGray
- property int borderFocusedWidth: 1
-
- property string checkedIndicatorBorderColor: AmneziaStyle.color.richBrown
- property string defaultIndicatorBorderColor: AmneziaStyle.color.charcoalGray
- property string checkedDisabledIndicatorBorderColor: AmneziaStyle.color.deepBrown
-
- property string checkedInnerCircleColor: AmneziaStyle.color.goldenApricot
- property string defaultInnerCircleColor: AmneziaStyle.color.paleGray
- property string checkedDisabledInnerCircleColor: AmneziaStyle.color.mutedBrown
- property string defaultDisabledInnerCircleColor: AmneziaStyle.color.charcoalGray
-
- property string hoveredIndicatorBackgroundColor: AmneziaStyle.color.translucentWhite
- property string defaultIndicatorBackgroundColor: AmneziaStyle.color.transparent
-
- property bool isFocusable: true
-
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
- hoverEnabled: enabled ? true : false
- focusPolicy: Qt.TabFocus
-
- property FlickableType parentFlickable: null
-
- onFocusChanged: {
- if (root.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(root)
- }
- }
- }
-
- indicator: Rectangle {
- id: switcher
-
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
-
- implicitWidth: 52
- implicitHeight: 32
-
- radius: 16
- color: root.checked ? (root.enabled ? root.checkedIndicatorColor : root.checkedDisabledIndicatorColor)
- : root.defaultIndicatorColor
-
- border.color: root.activeFocus ? root.borderFocusedColor : (root.checked ? (root.enabled ? root.checkedIndicatorBorderColor : root.checkedDisabledIndicatorBorderColor)
- : root.defaultIndicatorBorderColor)
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
- Behavior on border.color {
- PropertyAnimation { duration: 200 }
- }
-
- Rectangle {
- id: innerCircle
-
- anchors.verticalCenter: parent.verticalCenter
- x: root.checked ? parent.width - width - 4 : 8
- width: root.checked ? 24 : 16
- height: root.checked ? 24 : 16
- radius: 23
- color: root.checked ? (root.enabled ? root.checkedInnerCircleColor : root.checkedDisabledInnerCircleColor)
- : (root.enabled ? root.defaultInnerCircleColor : root.defaultDisabledInnerCircleColor)
-
- Behavior on x {
- PropertyAnimation { duration: 200 }
- }
- }
-
- Rectangle {
- anchors.centerIn: innerCircle
- width: 40
- height: 40
- radius: 23
- color: root.hovered ? root.hoveredIndicatorBackgroundColor : root.defaultIndicatorBackgroundColor
-
- Behavior on color {
- PropertyAnimation { duration: 200 }
- }
- }
- }
-
- contentItem: ColumnLayout {
- id: content
-
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
-
- ListItemTitleType {
- Layout.fillWidth: true
- rightPadding: indicator.width
-
- text: root.text
- color: root.enabled ? root.textColor : root.textDisabledColor
- }
-
- CaptionTextType {
- id: description
-
- Layout.fillWidth: true
- rightPadding: indicator.width
-
- color: root.enabled ? root.descriptionTextColor : root.descriptionTextDisabledColor
-
- visible: text !== ""
- }
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- enabled: false
- }
-
- Keys.onEnterPressed: event => handleSwitch(event)
- Keys.onReturnPressed: event => handleSwitch(event)
- Keys.onSpacePressed: event => handleSwitch(event)
-
- function handleSwitch(event) {
- if (!event.isAutoRepeat) {
- root.checked = !root.checked
- root.checkedChanged()
- }
- event.accepted = true
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import Style 1.0
+
+import "TextTypes"
+
+Switch {
+ id: root
+
+ property alias descriptionText: description.text
+ property string descriptionTextColor: AmneziaStyle.color.mutedGray
+ property string descriptionTextDisabledColor: AmneziaStyle.color.charcoalGray
+
+ property string textColor: AmneziaStyle.color.paleGray
+ property string textDisabledColor: AmneziaStyle.color.mutedGray
+
+ property string checkedIndicatorColor: AmneziaStyle.color.richBrown
+ property string defaultIndicatorColor: AmneziaStyle.color.transparent
+ property string checkedDisabledIndicatorColor: AmneziaStyle.color.deepBrown
+
+ property string borderFocusedColor: AmneziaStyle.color.paleGray
+ property int borderFocusedWidth: 1
+
+ property string checkedIndicatorBorderColor: AmneziaStyle.color.richBrown
+ property string defaultIndicatorBorderColor: AmneziaStyle.color.charcoalGray
+ property string checkedDisabledIndicatorBorderColor: AmneziaStyle.color.deepBrown
+
+ property string checkedInnerCircleColor: AmneziaStyle.color.goldenApricot
+ property string defaultInnerCircleColor: AmneziaStyle.color.paleGray
+ property string checkedDisabledInnerCircleColor: AmneziaStyle.color.mutedBrown
+ property string defaultDisabledInnerCircleColor: AmneziaStyle.color.charcoalGray
+
+ property string hoveredIndicatorBackgroundColor: AmneziaStyle.color.translucentWhite
+ property string defaultIndicatorBackgroundColor: AmneziaStyle.color.transparent
+
+ property bool isFocusable: true
+
+ Keys.onTabPressed: {
+ FocusController.nextKeyTabItem()
+ }
+
+ Keys.onBacktabPressed: {
+ FocusController.previousKeyTabItem()
+ }
+
+ Keys.onUpPressed: {
+ FocusController.nextKeyUpItem()
+ }
+
+ Keys.onDownPressed: {
+ FocusController.nextKeyDownItem()
+ }
+
+ Keys.onLeftPressed: {
+ FocusController.nextKeyLeftItem()
+ }
+
+ Keys.onRightPressed: {
+ FocusController.nextKeyRightItem()
+ }
+
+ hoverEnabled: enabled ? true : false
+ focusPolicy: Qt.TabFocus
+
+ indicator: Rectangle {
+ id: switcher
+
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+
+ implicitWidth: 52
+ implicitHeight: 32
+
+ radius: 16
+ color: root.checked ? (root.enabled ? root.checkedIndicatorColor : root.checkedDisabledIndicatorColor)
+ : root.defaultIndicatorColor
+
+ border.color: root.activeFocus ? root.borderFocusedColor : (root.checked ? (root.enabled ? root.checkedIndicatorBorderColor : root.checkedDisabledIndicatorBorderColor)
+ : root.defaultIndicatorBorderColor)
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ Behavior on border.color {
+ PropertyAnimation { duration: 200 }
+ }
+
+ Rectangle {
+ id: innerCircle
+
+ anchors.verticalCenter: parent.verticalCenter
+ x: root.checked ? parent.width - width - 4 : 8
+ width: root.checked ? 24 : 16
+ height: root.checked ? 24 : 16
+ radius: 23
+ color: root.checked ? (root.enabled ? root.checkedInnerCircleColor : root.checkedDisabledInnerCircleColor)
+ : (root.enabled ? root.defaultInnerCircleColor : root.defaultDisabledInnerCircleColor)
+
+ Behavior on x {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+
+ Rectangle {
+ anchors.centerIn: innerCircle
+ width: 40
+ height: 40
+ radius: 23
+ color: root.hovered ? root.hoveredIndicatorBackgroundColor : root.defaultIndicatorBackgroundColor
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+ }
+
+ contentItem: ColumnLayout {
+ id: content
+
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+
+ ListItemTitleType {
+ Layout.fillWidth: true
+ rightPadding: indicator.width
+
+ text: root.text
+ color: root.enabled ? root.textColor : root.textDisabledColor
+ }
+
+ CaptionTextType {
+ id: description
+
+ Layout.fillWidth: true
+ rightPadding: indicator.width
+
+ color: root.enabled ? root.descriptionTextColor : root.descriptionTextDisabledColor
+
+ visible: text !== ""
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
+
+ Keys.onEnterPressed: event => handleSwitch(event)
+ Keys.onReturnPressed: event => handleSwitch(event)
+ Keys.onSpacePressed: event => handleSwitch(event)
+
+ function handleSwitch(event) {
+ if (!event.isAutoRepeat) {
+ root.checked = !root.checked
+ root.checkedChanged()
+ }
+ event.accepted = true
+ }
+}
diff --git a/client/ui/qml/Controls2/TextAreaType.qml b/client/ui/qml/Controls2/TextAreaType.qml
index 9359fa16..7b6721dd 100644
--- a/client/ui/qml/Controls2/TextAreaType.qml
+++ b/client/ui/qml/Controls2/TextAreaType.qml
@@ -1,118 +1,135 @@
-import QtQuick
-import QtQuick.Controls
-
-import Style 1.0
-
-Rectangle {
- id: root
-
- property string placeholderText
- property string text
- property alias textArea: textArea
- property alias textAreaText: textArea.text
-
- property string borderHoveredColor: AmneziaStyle.color.charcoalGray
- property string borderNormalColor: AmneziaStyle.color.slateGray
- property string borderFocusedColor: AmneziaStyle.color.paleGray
-
- height: 148
- color: AmneziaStyle.color.onyxBlack
- border.width: 1
- border.color: getBorderColor(borderNormalColor)
- radius: 16
-
- property FlickableType parentFlickable: null
- onFocusChanged: {
- if (root.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(root)
- }
- }
- }
-
- MouseArea {
- id: parentMouse
- anchors.fill: parent
- cursorShape: Qt.IBeamCursor
- onClicked: textArea.forceActiveFocus()
- hoverEnabled: true
-
- FlickableType {
- id: fl
- interactive: false
-
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- contentHeight: textArea.implicitHeight
- TextArea {
- id: textArea
-
- width: parent.width
-
- topPadding: 16
- leftPadding: 16
- anchors.topMargin: 16
- anchors.bottomMargin: 16
-
- color: AmneziaStyle.color.paleGray
- selectionColor: AmneziaStyle.color.richBrown
- selectedTextColor: AmneziaStyle.color.paleGray
- placeholderTextColor: AmneziaStyle.color.mutedGray
-
- font.pixelSize: 16
- font.weight: Font.Medium
- font.family: "PT Root UI VF"
-
- placeholderText: root.placeholderText
- text: root.text
-
- onCursorVisibleChanged: {
- if (textArea.cursorVisible) {
- fl.interactive = true
- } else {
- fl.interactive = false
- }
- }
-
- wrapMode: Text.Wrap
-
- MouseArea {
- id: textAreaMouse
- anchors.fill: parent
- acceptedButtons: Qt.RightButton
- hoverEnabled: true
- onClicked: {
- fl.interactive = true
- contextMenu.open()
- }
- }
-
- onFocusChanged: {
- root.border.color = getBorderColor(borderNormalColor)
- }
-
- ContextMenuType {
- id: contextMenu
- textObj: textArea
- }
- }
- }
-
- onPressed: {
- root.border.color = getBorderColor(borderFocusedColor)
- }
-
- onExited: {
- root.border.color = getBorderColor(borderNormalColor)
- }
-
- onEntered: {
- root.border.color = getBorderColor(borderHoveredColor)
- }
- }
-
-
- function getBorderColor(noneFocusedColor) {
- return textArea.focus ? root.borderFocusedColor : noneFocusedColor
- }
-}
+import QtQuick
+import QtQuick.Controls
+
+import Style 1.0
+
+Rectangle {
+ id: root
+
+ property string placeholderText
+ property string text
+ property alias textArea: textArea
+ property alias textAreaText: textArea.text
+
+ property string borderHoveredColor: AmneziaStyle.color.charcoalGray
+ property string borderNormalColor: AmneziaStyle.color.slateGray
+ property string borderFocusedColor: AmneziaStyle.color.paleGray
+
+ height: 148
+ color: AmneziaStyle.color.onyxBlack
+ border.width: 1
+ border.color: getBorderColor(borderNormalColor)
+ radius: 16
+
+ MouseArea {
+ id: parentMouse
+ anchors.fill: parent
+ cursorShape: Qt.IBeamCursor
+ onClicked: textArea.forceActiveFocus()
+ hoverEnabled: true
+
+ FlickableType {
+ id: fl
+ interactive: false
+
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ contentHeight: textArea.implicitHeight
+ TextArea {
+ id: textArea
+
+ width: parent.width
+
+ topPadding: 16
+ leftPadding: 16
+ anchors.topMargin: 16
+ anchors.bottomMargin: 16
+
+ property bool isFocusable: true
+
+ Keys.onTabPressed: {
+ FocusController.nextKeyTabItem()
+ }
+
+ Keys.onBacktabPressed: {
+ FocusController.previousKeyTabItem()
+ }
+
+ Keys.onUpPressed: {
+ FocusController.nextKeyUpItem()
+ }
+
+ Keys.onDownPressed: {
+ FocusController.nextKeyDownItem()
+ }
+
+ Keys.onLeftPressed: {
+ FocusController.nextKeyLeftItem()
+ }
+
+ Keys.onRightPressed: {
+ FocusController.nextKeyRightItem()
+ }
+
+ color: AmneziaStyle.color.paleGray
+ selectionColor: AmneziaStyle.color.richBrown
+ selectedTextColor: AmneziaStyle.color.paleGray
+ placeholderTextColor: AmneziaStyle.color.mutedGray
+
+ font.pixelSize: 16
+ font.weight: Font.Medium
+ font.family: "PT Root UI VF"
+
+ placeholderText: root.placeholderText
+ text: root.text
+
+ onCursorVisibleChanged: {
+ if (textArea.cursorVisible) {
+ fl.interactive = true
+ } else {
+ fl.interactive = false
+ }
+ }
+
+ wrapMode: Text.Wrap
+
+ MouseArea {
+ id: textAreaMouse
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ hoverEnabled: true
+ onClicked: {
+ fl.interactive = true
+ contextMenu.open()
+ }
+ }
+
+ onFocusChanged: {
+ root.border.color = getBorderColor(borderNormalColor)
+ }
+
+ ContextMenuType {
+ id: contextMenu
+ textObj: textArea
+ }
+ }
+ }
+
+ onPressed: {
+ root.border.color = getBorderColor(borderFocusedColor)
+ }
+
+ onExited: {
+ root.border.color = getBorderColor(borderNormalColor)
+ }
+
+ onEntered: {
+ root.border.color = getBorderColor(borderHoveredColor)
+ }
+ }
+
+
+ function getBorderColor(noneFocusedColor) {
+ return textArea.focus ? root.borderFocusedColor : noneFocusedColor
+ }
+}
diff --git a/client/ui/qml/Controls2/TextAreaWithFooterType.qml b/client/ui/qml/Controls2/TextAreaWithFooterType.qml
index cf7b9146..2cb6a69c 100644
--- a/client/ui/qml/Controls2/TextAreaWithFooterType.qml
+++ b/client/ui/qml/Controls2/TextAreaWithFooterType.qml
@@ -1,180 +1,171 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-
-import Style 1.0
-
-import "TextTypes"
-
-Rectangle {
- id: root
-
- property string placeholderText
- property string text
- property string headerText
- property alias textArea: textArea
- property alias textAreaText: textArea.text
-
- property string borderHoveredColor: AmneziaStyle.color.charcoalGray
- property string borderNormalColor: AmneziaStyle.color.slateGray
- property string borderFocusedColor: AmneziaStyle.color.paleGray
-
- property string firstButtonImage
- property string secondButtonImage
-
- property var firstButtonClickedFunc
- property var secondButtonClickedFunc
-
- height: 148
- color: AmneziaStyle.color.onyxBlack
- border.width: 1
- border.color: getBorderColor(borderNormalColor)
- radius: 16
-
- property FlickableType parentFlickable: null
- onFocusChanged: {
- if (root.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(root)
- }
- }
- }
-
- MouseArea {
- id: parentMouse
- anchors.fill: parent
- cursorShape: Qt.IBeamCursor
- onClicked: textArea.forceActiveFocus()
- hoverEnabled: true
-
- ColumnLayout {
- anchors.fill: parent
- anchors.margins: 16
- spacing: 0
-
- LabelTextType {
- Layout.fillWidth: true
- text: root.headerText
- }
-
- TextArea {
- id: textArea
-
- Layout.fillWidth: true
- Layout.fillHeight: true
-
- leftPadding: 0
- Layout.bottomMargin: 16
-
- color: AmneziaStyle.color.paleGray
- selectionColor: AmneziaStyle.color.richBrown
- selectedTextColor: AmneziaStyle.color.paleGray
- placeholderTextColor: AmneziaStyle.color.mutedGray
-
- font.pixelSize: 16
- font.weight: Font.Medium
- font.family: "PT Root UI VF"
-
- placeholderText: root.placeholderText
- text: root.text
-
- onCursorVisibleChanged: {
- if (textArea.cursorVisible) {
- fl.interactive = true
- } else {
- fl.interactive = false
- }
- }
-
- wrapMode: Text.Wrap
-
- MouseArea {
- id: textAreaMouse
- anchors.fill: parent
- acceptedButtons: Qt.RightButton
- hoverEnabled: true
- onClicked: {
- fl.interactive = true
- contextMenu.open()
- }
- }
-
- onFocusChanged: {
- root.border.color = getBorderColor(borderNormalColor)
- }
-
- ContextMenuType {
- id: contextMenu
- textObj: textArea
- }
- }
-
- RowLayout {
- Layout.fillWidth: true
- Layout.leftMargin: -8
- spacing: 0
- ImageButtonType {
- id: firstButton
- visible: root.firstButtonImage !== ""
-
- imageColor: AmneziaStyle.color.paleGray
-
- image: root.firstButtonImage
- onClicked: function() {
- if (root.firstButtonClickedFunc && typeof root.firstButtonClickedFunc === "function") {
- root.firstButtonClickedFunc()
- }
- }
- }
-
- ImageButtonType {
- id: secondButton
- visible: root.secondButtonImage !== ""
-
- imageColor: AmneziaStyle.color.paleGray
-
- image: root.secondButtonImage
- onClicked: function() {
- if (root.secondButtonClickedFunc && typeof root.secondButtonClickedFunc === "function") {
- root.secondButtonClickedFunc()
- }
- }
- }
-
- Item {
- Layout.fillWidth: true
- }
-
- ImageButtonType {
- id: resetButton
- imageColor: AmneziaStyle.color.paleGray
-
- visible: root.textAreaText !== ""
- image: "qrc:/images/controls/close.svg"
-
- onClicked: function() {
- root.textAreaText = ""
- textArea.focus = true
- }
- }
- }
- }
-
- onPressed: {
- root.border.color = getBorderColor(borderFocusedColor)
- }
-
- onExited: {
- root.border.color = getBorderColor(borderNormalColor)
- }
-
- onEntered: {
- root.border.color = getBorderColor(borderHoveredColor)
- }
- }
-
-
- function getBorderColor(noneFocusedColor) {
- return textArea.focus ? root.borderFocusedColor : noneFocusedColor
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import Style 1.0
+
+import "TextTypes"
+
+Rectangle {
+ id: root
+
+ property string placeholderText
+ property string text
+ property string headerText
+ property alias textArea: textArea
+ property alias textAreaText: textArea.text
+
+ property string borderHoveredColor: AmneziaStyle.color.charcoalGray
+ property string borderNormalColor: AmneziaStyle.color.slateGray
+ property string borderFocusedColor: AmneziaStyle.color.paleGray
+
+ property string firstButtonImage
+ property string secondButtonImage
+
+ property var firstButtonClickedFunc
+ property var secondButtonClickedFunc
+
+ height: 148
+ color: AmneziaStyle.color.onyxBlack
+ border.width: 1
+ border.color: getBorderColor(borderNormalColor)
+ radius: 16
+
+ MouseArea {
+ id: parentMouse
+ anchors.fill: parent
+ cursorShape: Qt.IBeamCursor
+ onClicked: textArea.forceActiveFocus()
+ hoverEnabled: true
+
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: 16
+ spacing: 0
+
+ LabelTextType {
+ Layout.fillWidth: true
+ text: root.headerText
+ }
+
+ TextArea {
+ id: textArea
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ leftPadding: 0
+ Layout.bottomMargin: 16
+
+ color: AmneziaStyle.color.paleGray
+ selectionColor: AmneziaStyle.color.richBrown
+ selectedTextColor: AmneziaStyle.color.paleGray
+ placeholderTextColor: AmneziaStyle.color.mutedGray
+
+ font.pixelSize: 16
+ font.weight: Font.Medium
+ font.family: "PT Root UI VF"
+
+ placeholderText: root.placeholderText
+ text: root.text
+
+ onCursorVisibleChanged: {
+ if (textArea.cursorVisible) {
+ fl.interactive = true
+ } else {
+ fl.interactive = false
+ }
+ }
+
+ wrapMode: Text.Wrap
+
+ MouseArea {
+ id: textAreaMouse
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ hoverEnabled: true
+ onClicked: {
+ fl.interactive = true
+ contextMenu.open()
+ }
+ }
+
+ onFocusChanged: {
+ root.border.color = getBorderColor(borderNormalColor)
+ }
+
+ ContextMenuType {
+ id: contextMenu
+ textObj: textArea
+ }
+ }
+
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.leftMargin: -8
+ spacing: 0
+ ImageButtonType {
+ id: firstButton
+ visible: root.firstButtonImage !== ""
+
+ imageColor: AmneziaStyle.color.paleGray
+
+ image: root.firstButtonImage
+ onClicked: function() {
+ if (root.firstButtonClickedFunc && typeof root.firstButtonClickedFunc === "function") {
+ root.firstButtonClickedFunc()
+ }
+ }
+ }
+
+ ImageButtonType {
+ id: secondButton
+ visible: root.secondButtonImage !== ""
+
+ imageColor: AmneziaStyle.color.paleGray
+
+ image: root.secondButtonImage
+ onClicked: function() {
+ if (root.secondButtonClickedFunc && typeof root.secondButtonClickedFunc === "function") {
+ root.secondButtonClickedFunc()
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ ImageButtonType {
+ id: resetButton
+ imageColor: AmneziaStyle.color.paleGray
+
+ visible: root.textAreaText !== ""
+ image: "qrc:/images/controls/close.svg"
+
+ onClicked: function() {
+ root.textAreaText = ""
+ textArea.focus = true
+ }
+ }
+ }
+ }
+
+ onPressed: {
+ root.border.color = getBorderColor(borderFocusedColor)
+ }
+
+ onExited: {
+ root.border.color = getBorderColor(borderNormalColor)
+ }
+
+ onEntered: {
+ root.border.color = getBorderColor(borderHoveredColor)
+ }
+ }
+
+
+ function getBorderColor(noneFocusedColor) {
+ return textArea.focus ? root.borderFocusedColor : noneFocusedColor
+ }
+}
diff --git a/client/ui/qml/Controls2/TextFieldWithHeaderType.qml b/client/ui/qml/Controls2/TextFieldWithHeaderType.qml
index c4ed91b3..d7697867 100644
--- a/client/ui/qml/Controls2/TextFieldWithHeaderType.qml
+++ b/client/ui/qml/Controls2/TextFieldWithHeaderType.qml
@@ -1,233 +1,220 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-
-import Style 1.0
-
-import "TextTypes"
-
-Item {
- id: root
-
- property string headerText
- property string headerTextDisabledColor: AmneziaStyle.color.charcoalGray
- property string headerTextColor: AmneziaStyle.color.mutedGray
-
- property alias errorText: errorField.text
- property bool checkEmptyText: false
- property bool rightButtonClickedOnEnter: false
-
- property string buttonText
- property string buttonImageSource
- property var clickedFunc
-
- property alias textField: textField
- property string textFieldTextColor: AmneziaStyle.color.paleGray
- property string textFieldTextDisabledColor: AmneziaStyle.color.mutedGray
-
- property bool textFieldEditable: true
-
- property string borderColor: AmneziaStyle.color.slateGray
- property string borderFocusedColor: AmneziaStyle.color.paleGray
-
- property string backgroundColor: AmneziaStyle.color.onyxBlack
- property string backgroundDisabledColor: AmneziaStyle.color.transparent
- property string bgBorderHoveredColor: AmneziaStyle.color.charcoalGray
-
- implicitWidth: content.implicitWidth
- implicitHeight: content.implicitHeight
-
- property FlickableType parentFlickable
-
- Connections {
- target: textField
- function onFocusChanged() {
- if (textField.activeFocus) {
- if (root.parentFlickable) {
- root.parentFlickable.ensureVisible(root)
- }
- }
- }
- }
-
- ColumnLayout {
- id: content
- anchors.fill: parent
-
- Rectangle {
- id: backgroud
- Layout.fillWidth: true
- Layout.preferredHeight: input.implicitHeight
- color: root.enabled ? root.backgroundColor : root.backgroundDisabledColor
- radius: 16
- border.color: getBackgroundBorderColor(root.borderColor)
- border.width: 1
-
- Behavior on border.color {
- PropertyAnimation { duration: 200 }
- }
-
- RowLayout {
- id: input
- anchors.fill: backgroud
- ColumnLayout {
- Layout.margins: 16
- LabelTextType {
- text: root.headerText
- color: root.enabled ? root.headerTextColor : root.headerTextDisabledColor
-
- visible: text !== ""
-
- Layout.fillWidth: true
- }
-
- TextField {
- id: textField
-
- property bool isFocusable: true
-
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- enabled: root.textFieldEditable
- color: root.enabled ? root.textFieldTextColor : root.textFieldTextDisabledColor
-
- inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText
-
- placeholderTextColor: AmneziaStyle.color.charcoalGray
-
- selectionColor: AmneziaStyle.color.richBrown
- selectedTextColor: AmneziaStyle.color.paleGray
-
- font.pixelSize: 16
- font.weight: 400
- font.family: "PT Root UI VF"
-
- height: 24
- Layout.fillWidth: true
-
- topPadding: 0
- rightPadding: 0
- leftPadding: 0
- bottomPadding: 0
-
- background: Rectangle {
- anchors.fill: parent
- color: root.enabled ? root.backgroundColor : root.backgroundDisabledColor
- }
-
- onTextChanged: {
- root.errorText = ""
- }
-
- onActiveFocusChanged: {
- if (root.checkEmptyText && text === "") {
- root.errorText = qsTr("The field can't be empty")
- }
- }
-
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.RightButton
- onClicked: contextMenu.open()
- enabled: true
- }
-
- ContextMenuType {
- id: contextMenu
- textObj: textField
- }
-
- onFocusChanged: {
- backgroud.border.color = getBackgroundBorderColor(root.borderColor)
- }
- }
- }
- }
- }
-
- SmallTextType {
- id: errorField
-
- text: root.errorText
- visible: root.errorText !== ""
- color: AmneziaStyle.color.vibrantRed
-
- Layout.fillWidth: true
- }
- }
-
- MouseArea {
- anchors.fill: root
- cursorShape: Qt.IBeamCursor
-
- hoverEnabled: true
-
- onPressed: function(mouse) {
- textField.forceActiveFocus()
- mouse.accepted = false
-
- backgroud.border.color = getBackgroundBorderColor(root.borderColor)
- }
-
- onEntered: {
- backgroud.border.color = getBackgroundBorderColor(bgBorderHoveredColor)
- }
-
-
- onExited: {
- backgroud.border.color = getBackgroundBorderColor(root.borderColor)
- }
- }
-
- BasicButtonType {
- visible: (root.buttonText !== "") || (root.buttonImageSource !== "")
-
- focusPolicy: Qt.NoFocus
- text: root.buttonText
- leftImageSource: root.buttonImageSource
-
- anchors.top: content.top
- anchors.bottom: content.bottom
- anchors.right: content.right
-
- height: content.implicitHeight
- width: content.implicitHeight
- squareLeftSide: true
-
- clickedFunc: function() {
- if (root.clickedFunc && typeof root.clickedFunc === "function") {
- root.clickedFunc()
- }
- }
- }
-
- function getBackgroundBorderColor(noneFocusedColor) {
- return textField.focus ? root.borderFocusedColor : noneFocusedColor
- }
-
- Keys.onEnterPressed: {
- if (root.rightButtonClickedOnEnter && root.clickedFunc && typeof root.clickedFunc === "function") {
- clickedFunc()
- }
-
- // if (KeyNavigation.tab) {
- // KeyNavigation.tab.forceActiveFocus();
- // }
- }
-
- Keys.onReturnPressed: {
- if (root.rightButtonClickedOnEnter &&root.clickedFunc && typeof root.clickedFunc === "function") {
- clickedFunc()
- }
-
- // if (KeyNavigation.tab) {
- // KeyNavigation.tab.forceActiveFocus();
- // }
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import Style 1.0
+
+import "TextTypes"
+
+Item {
+ id: root
+
+ property string headerText
+ property string headerTextDisabledColor: AmneziaStyle.color.charcoalGray
+ property string headerTextColor: AmneziaStyle.color.mutedGray
+
+ property alias errorText: errorField.text
+ property bool checkEmptyText: false
+ property bool rightButtonClickedOnEnter: false
+
+ property string buttonText
+ property string buttonImageSource
+ property var clickedFunc
+
+ property alias textField: textField
+ property string textFieldTextColor: AmneziaStyle.color.paleGray
+ property string textFieldTextDisabledColor: AmneziaStyle.color.mutedGray
+
+ property bool textFieldEditable: true
+
+ property string borderColor: AmneziaStyle.color.slateGray
+ property string borderFocusedColor: AmneziaStyle.color.paleGray
+
+ property string backgroundColor: AmneziaStyle.color.onyxBlack
+ property string backgroundDisabledColor: AmneziaStyle.color.transparent
+ property string bgBorderHoveredColor: AmneziaStyle.color.charcoalGray
+
+ implicitWidth: content.implicitWidth
+ implicitHeight: content.implicitHeight
+
+ ColumnLayout {
+ id: content
+ anchors.fill: parent
+
+ Rectangle {
+ id: backgroud
+ Layout.fillWidth: true
+ Layout.preferredHeight: input.implicitHeight
+ color: root.enabled ? root.backgroundColor : root.backgroundDisabledColor
+ radius: 16
+ border.color: getBackgroundBorderColor(root.borderColor)
+ border.width: 1
+
+ Behavior on border.color {
+ PropertyAnimation { duration: 200 }
+ }
+
+ RowLayout {
+ id: input
+ anchors.fill: backgroud
+ ColumnLayout {
+ Layout.margins: 16
+ LabelTextType {
+ text: root.headerText
+ color: root.enabled ? root.headerTextColor : root.headerTextDisabledColor
+
+ visible: text !== ""
+
+ Layout.fillWidth: true
+ }
+
+ TextField {
+ id: textField
+
+ property bool isFocusable: true
+
+ Keys.onTabPressed: {
+ FocusController.nextKeyTabItem()
+ }
+
+ Keys.onBacktabPressed: {
+ FocusController.previousKeyTabItem()
+ }
+
+ enabled: root.textFieldEditable
+ color: root.enabled ? root.textFieldTextColor : root.textFieldTextDisabledColor
+
+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText
+
+ placeholderTextColor: AmneziaStyle.color.charcoalGray
+
+ selectionColor: AmneziaStyle.color.richBrown
+ selectedTextColor: AmneziaStyle.color.paleGray
+
+ font.pixelSize: 16
+ font.weight: 400
+ font.family: "PT Root UI VF"
+
+ height: 24
+ Layout.fillWidth: true
+
+ topPadding: 0
+ rightPadding: 0
+ leftPadding: 0
+ bottomPadding: 0
+
+ background: Rectangle {
+ anchors.fill: parent
+ color: root.enabled ? root.backgroundColor : root.backgroundDisabledColor
+ }
+
+ onTextChanged: {
+ root.errorText = ""
+ }
+
+ onActiveFocusChanged: {
+ if (root.checkEmptyText && text === "") {
+ root.errorText = qsTr("The field can't be empty")
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ onClicked: contextMenu.open()
+ enabled: true
+ }
+
+ ContextMenuType {
+ id: contextMenu
+ textObj: textField
+ }
+
+ onFocusChanged: {
+ backgroud.border.color = getBackgroundBorderColor(root.borderColor)
+ }
+ }
+ }
+ }
+ }
+
+ SmallTextType {
+ id: errorField
+
+ text: root.errorText
+ visible: root.errorText !== ""
+ color: AmneziaStyle.color.vibrantRed
+
+ Layout.fillWidth: true
+ }
+ }
+
+ MouseArea {
+ anchors.fill: root
+ cursorShape: Qt.IBeamCursor
+
+ hoverEnabled: true
+
+ onPressed: function(mouse) {
+ textField.forceActiveFocus()
+ mouse.accepted = false
+
+ backgroud.border.color = getBackgroundBorderColor(root.borderColor)
+ }
+
+ onEntered: {
+ backgroud.border.color = getBackgroundBorderColor(bgBorderHoveredColor)
+ }
+
+
+ onExited: {
+ backgroud.border.color = getBackgroundBorderColor(root.borderColor)
+ }
+ }
+
+ BasicButtonType {
+ visible: (root.buttonText !== "") || (root.buttonImageSource !== "")
+
+ focusPolicy: Qt.NoFocus
+ text: root.buttonText
+ leftImageSource: root.buttonImageSource
+
+ anchors.top: content.top
+ anchors.bottom: content.bottom
+ anchors.right: content.right
+
+ height: content.implicitHeight
+ width: content.implicitHeight
+ squareLeftSide: true
+
+ clickedFunc: function() {
+ if (root.clickedFunc && typeof root.clickedFunc === "function") {
+ root.clickedFunc()
+ }
+ }
+ }
+
+ function getBackgroundBorderColor(noneFocusedColor) {
+ return textField.focus ? root.borderFocusedColor : noneFocusedColor
+ }
+
+ Keys.onEnterPressed: {
+ if (root.rightButtonClickedOnEnter && root.clickedFunc && typeof root.clickedFunc === "function") {
+ clickedFunc()
+ }
+
+ // if (KeyNavigation.tab) {
+ // KeyNavigation.tab.forceActiveFocus();
+ // }
+ }
+
+ Keys.onReturnPressed: {
+ if (root.rightButtonClickedOnEnter &&root.clickedFunc && typeof root.clickedFunc === "function") {
+ clickedFunc()
+ }
+
+ // if (KeyNavigation.tab) {
+ // KeyNavigation.tab.forceActiveFocus();
+ // }
+ }
+}
diff --git a/client/ui/qml/Pages2/PageDeinstalling.qml b/client/ui/qml/Pages2/PageDeinstalling.qml
index 69b1f319..03d26f8d 100644
--- a/client/ui/qml/Pages2/PageDeinstalling.qml
+++ b/client/ui/qml/Pages2/PageDeinstalling.qml
@@ -20,7 +20,9 @@ PageType {
SortFilterProxyModel {
id: proxyServersModel
+
sourceModel: ServersModel
+
filters: [
ValueFilter {
roleName: "isCurrentlyProcessed"
@@ -29,67 +31,55 @@ PageType {
]
}
- FlickableType {
- id: fl
+ ListViewType {
+ id: listView
+
anchors.fill: parent
- contentHeight: content.height
- Column {
- id: content
+ spacing: 16
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ model: proxyServersModel
- spacing: 16
+ delegate: ColumnLayout {
+ width: listView.width
- Repeater {
- model: proxyServersModel
- delegate: Item {
- implicitWidth: parent.width
- implicitHeight: delegateContent.implicitHeight
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.topMargin: 20
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- ColumnLayout {
- id: delegateContent
+ headerText: qsTr("Removing services from %1").arg(name)
+ }
- anchors.fill: parent
- anchors.rightMargin: 16
- anchors.leftMargin: 16
+ ProgressBarType {
+ id: progressBar
- BaseHeaderType {
- Layout.fillWidth: true
- Layout.topMargin: 20
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- headerText: qsTr("Removing services from %1").arg(name)
- }
+ Timer {
+ id: timer
- ProgressBarType {
- id: progressBar
-
- Layout.fillWidth: true
- Layout.topMargin: 32
-
- Timer {
- id: timer
-
- interval: 300
- repeat: true
- running: true
- onTriggered: {
- progressBar.value += 0.003
- }
- }
- }
-
- ParagraphTextType {
- Layout.fillWidth: true
- Layout.topMargin: 8
-
- text: qsTr("Usually it takes no more than 5 minutes")
- }
+ interval: 300
+ repeat: true
+ running: true
+ onTriggered: {
+ progressBar.value += 0.003
}
}
}
+
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.topMargin: 8
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Usually it takes no more than 5 minutes")
+ }
}
}
}
diff --git a/client/ui/qml/Pages2/PageDevMenu.qml b/client/ui/qml/Pages2/PageDevMenu.qml
index 5fccb43a..9f042fad 100644
--- a/client/ui/qml/Pages2/PageDevMenu.qml
+++ b/client/ui/qml/Pages2/PageDevMenu.qml
@@ -25,23 +25,17 @@ PageType {
anchors.topMargin: 20
}
- ListView {
+ ListViewType {
id: listView
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
- property bool isFocusable: true
-
- ScrollBar.vertical: ScrollBarType {}
-
header: ColumnLayout {
width: listView.width
BaseHeaderType {
- id: header
-
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
@@ -50,16 +44,14 @@ PageType {
}
}
- model: 1
- clip: true
+ model: 1 // fake model to force the ListView to be created without a model
+
spacing: 16
delegate: ColumnLayout {
width: listView.width
TextFieldWithHeaderType {
- id: passwordTextField
-
Layout.fillWidth: true
Layout.topMargin: 16
Layout.rightMargin: 16
@@ -87,8 +79,6 @@ PageType {
width: listView.width
SwitcherType {
- id: switcher
-
Layout.fillWidth: true
Layout.topMargin: 24
Layout.rightMargin: 16
diff --git a/client/ui/qml/Pages2/PageProtocolAwgClientSettings.qml b/client/ui/qml/Pages2/PageProtocolAwgClientSettings.qml
index d97d09e8..18db8119 100644
--- a/client/ui/qml/Pages2/PageProtocolAwgClientSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolAwgClientSettings.qml
@@ -16,349 +16,397 @@ import "../Components"
PageType {
id: root
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- ListView {
- id: listview
+ ListViewType {
+ id: listView
anchors.top: backButtonLayout.bottom
anchors.bottom: saveButton.top
+ anchors.right: parent.right
+ anchors.left: parent.left
- width: parent.width
+ header: ColumnLayout {
+ width: listView.width
+
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- clip: true
-
- property bool isFocusable: true
-
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
+ headerText: qsTr("AmneziaWG settings")
+ }
}
model: AwgConfigModel
- delegate: Item {
- id: delegateItem
- implicitWidth: listview.width
- implicitHeight: col.implicitHeight
+ delegate: ColumnLayout {
+ width: listView.width
- property alias mtuTextField: mtuTextField
property bool isSaveButtonEnabled: mtuTextField.errorText === "" &&
junkPacketMaxSizeTextField.errorText === "" &&
junkPacketMinSizeTextField.errorText === "" &&
junkPacketCountTextField.errorText === ""
- ColumnLayout {
- id: col
+ spacing: 0
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ TextFieldWithHeaderType {
+ id: mtuTextField
- anchors.leftMargin: 16
- anchors.rightMargin: 16
+ Layout.fillWidth: true
+ Layout.topMargin: 40
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- spacing: 0
+ headerText: qsTr("MTU")
+ textField.text: clientMtu
+ textField.validator: IntValidator { bottom: 576; top: 65535 }
- BaseHeaderType {
- Layout.fillWidth: true
-
- headerText: qsTr("AmneziaWG settings")
- }
-
- TextFieldWithHeaderType {
- id: mtuTextField
- Layout.fillWidth: true
- Layout.topMargin: 40
-
- headerText: qsTr("MTU")
- textField.text: clientMtu
- textField.validator: IntValidator { bottom: 576; top: 65535 }
-
- textField.onEditingFinished: {
- if (textField.text !== clientMtu) {
- clientMtu = textField.text
- }
- }
- checkEmptyText: true
- KeyNavigation.tab: junkPacketCountTextField.textField
- }
-
- AwgTextField {
- id: junkPacketCountTextField
- headerText: "Jc - Junk packet count"
- textField.text: clientJunkPacketCount
-
- textField.onEditingFinished: {
- if (textField.text !== clientJunkPacketCount) {
- clientJunkPacketCount = textField.text
- }
- }
-
- KeyNavigation.tab: junkPacketMinSizeTextField.textField
- }
-
- AwgTextField {
- id: junkPacketMinSizeTextField
- headerText: "Jmin - Junk packet minimum size"
- textField.text: clientJunkPacketMinSize
-
- textField.onEditingFinished: {
- if (textField.text !== clientJunkPacketMinSize) {
- clientJunkPacketMinSize = textField.text
- }
- }
-
- KeyNavigation.tab: junkPacketMaxSizeTextField.textField
- }
-
- AwgTextField {
- id: junkPacketMaxSizeTextField
- headerText: "Jmax - Junk packet maximum size"
- textField.text: clientJunkPacketMaxSize
-
- textField.onEditingFinished: {
- if (textField.text !== clientJunkPacketMaxSize) {
- clientJunkPacketMaxSize = textField.text
- }
+ textField.onEditingFinished: {
+ if (textField.text !== clientMtu) {
+ clientMtu = textField.text
}
}
+ checkEmptyText: true
+ }
- AwgTextField {
- id: specialJunk1TextField
- headerText: qsTr("I1 - First special junk packet")
- textField.text: clientSpecialJunk1
- textField.validator: null
- checkEmptyText: false
+ AwgTextField {
+ id: junkPacketCountTextField
- textField.onEditingFinished: {
- if (textField.text !== clientSpecialJunk1) {
- clientSpecialJunk1 = textField.text
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: "Jc - Junk packet count"
+ textField.text: clientJunkPacketCount
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientJunkPacketCount) {
+ clientJunkPacketCount = textField.text
}
}
+ }
- AwgTextField {
- id: specialJunk2TextField
- headerText: qsTr("I2 - Second special junk packet")
- textField.text: clientSpecialJunk2
- textField.validator: null
- checkEmptyText: false
+ AwgTextField {
+ id: junkPacketMinSizeTextField
- textField.onEditingFinished: {
- if (textField.text !== clientSpecialJunk2) {
- clientSpecialJunk2 = textField.text
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: "Jmin - Junk packet minimum size"
+ textField.text: clientJunkPacketMinSize
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientJunkPacketMinSize) {
+ clientJunkPacketMinSize = textField.text
}
}
+ }
- AwgTextField {
- id: specialJunk3TextField
- headerText: qsTr("I3 - Third special junk packet")
- textField.text: clientSpecialJunk3
- textField.validator: null
- checkEmptyText: false
+ AwgTextField {
+ id: junkPacketMaxSizeTextField
- textField.onEditingFinished: {
- if (textField.text !== clientSpecialJunk3) {
- clientSpecialJunk3 = textField.text
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: "Jmax - Junk packet maximum size"
+ textField.text: clientJunkPacketMaxSize
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientJunkPacketMaxSize) {
+ clientJunkPacketMaxSize = textField.text
}
}
+ }
- AwgTextField {
- id: specialJunk4TextField
- headerText: qsTr("I4 - Fourth special junk packet")
- textField.text: clientSpecialJunk4
- textField.validator: null
- checkEmptyText: false
+ AwgTextField {
+ id: specialJunk1TextField
- textField.onEditingFinished: {
- if (textField.text !== clientSpecialJunk4) {
- clientSpecialJunk4 = textField.text
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("I1 - First special junk packet")
+ textField.text: clientSpecialJunk1
+ textField.validator: null
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientSpecialJunk1) {
+ clientSpecialJunk1 = textField.text
}
}
+ }
- AwgTextField {
- id: specialJunk5TextField
- headerText: qsTr("I5 - Fifth special junk packet")
- textField.text: clientSpecialJunk5
- textField.validator: null
- checkEmptyText: false
+ AwgTextField {
+ id: specialJunk2TextField
- textField.onEditingFinished: {
- if (textField.text !== clientSpecialJunk5 ) {
- clientSpecialJunk5 = textField.text
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("I2 - Second special junk packet")
+ textField.text: clientSpecialJunk2
+ textField.validator: null
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientSpecialJunk2) {
+ clientSpecialJunk2 = textField.text
}
}
+ }
- AwgTextField {
- id: controlledJunk1TextField
- headerText: qsTr("J1 - First controlled junk packet")
- textField.text: clientControlledJunk1
- textField.validator: null
- checkEmptyText: false
+ AwgTextField {
+ id: specialJunk3TextField
- textField.onEditingFinished: {
- if (textField.text !== clientControlledJunk1) {
- clientControlledJunk1 = textField.text
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("I3 - Third special junk packet")
+ textField.text: clientSpecialJunk3
+ textField.validator: null
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientSpecialJunk3) {
+ clientSpecialJunk3 = textField.text
}
}
+ }
- AwgTextField {
- id: controlledJunk2TextField
- headerText: qsTr("J2 - Second controlled junk packet")
- textField.text: clientControlledJunk2
- textField.validator: null
- checkEmptyText: false
+ AwgTextField {
+ id: specialJunk4TextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- textField.onEditingFinished: {
- if (textField.text !== clientControlledJunk2) {
- clientControlledJunk2 = textField.text
- }
+ headerText: qsTr("I4 - Fourth special junk packet")
+ textField.text: clientSpecialJunk4
+ textField.validator: null
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientSpecialJunk4) {
+ clientSpecialJunk4 = textField.text
}
}
+ }
- AwgTextField {
- id: controlledJunk3TextField
- headerText: qsTr("J3 - Third controlled junk packet")
- textField.text: clientControlledJunk3
- textField.validator: null
- checkEmptyText: false
+ AwgTextField {
+ id: specialJunk5TextField
- textField.onEditingFinished: {
- if (textField.text !== clientControlledJunk3) {
- clientControlledJunk3 = textField.text
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("I5 - Fifth special junk packet")
+ textField.text: clientSpecialJunk5
+ textField.validator: null
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientSpecialJunk5 ) {
+ clientSpecialJunk5 = textField.text
}
}
+ }
- AwgTextField {
- id: iTimeTextField
- headerText: qsTr("Itime - Special handshake timeout")
- textField.text: clientSpecialHandshakeTimeout
- checkEmptyText: false
+ AwgTextField {
+ id: controlledJunk1TextField
- textField.onEditingFinished: {
- if (textField.text !== clientSpecialHandshakeTimeout) {
- clientSpecialHandshakeTimeout = textField.text
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("J1 - First controlled junk packet")
+ textField.text: clientControlledJunk1
+ textField.validator: null
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientControlledJunk1) {
+ clientControlledJunk1 = textField.text
}
}
+ }
- Header2TextType {
- Layout.fillWidth: true
- Layout.topMargin: 16
+ AwgTextField {
+ id: controlledJunk2TextField
- text: qsTr("Server settings")
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("J2 - Second controlled junk packet")
+ textField.text: clientControlledJunk2
+ textField.validator: null
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientControlledJunk2) {
+ clientControlledJunk2 = textField.text
+ }
}
+ }
- AwgTextField {
- id: portTextField
- enabled: false
+ AwgTextField {
+ id: controlledJunk3TextField
- headerText: qsTr("Port")
- textField.text: port
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("J3 - Third controlled junk packet")
+ textField.text: clientControlledJunk3
+ textField.validator: null
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientControlledJunk3) {
+ clientControlledJunk3 = textField.text
+ }
}
+ }
- AwgTextField {
- id: initPacketJunkSizeTextField
- enabled: false
+ AwgTextField {
+ id: iTimeTextField
- headerText: "S1 - Init packet junk size"
- textField.text: serverInitPacketJunkSize
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("Itime - Special handshake timeout")
+ textField.text: clientSpecialHandshakeTimeout
+ checkEmptyText: false
+
+ textField.onEditingFinished: {
+ if (textField.text !== clientSpecialHandshakeTimeout) {
+ clientSpecialHandshakeTimeout = textField.text
+ }
}
+ }
- AwgTextField {
- id: responsePacketJunkSizeTextField
- enabled: false
+ Header2TextType {
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- headerText: "S2 - Response packet junk size"
- textField.text: serverResponsePacketJunkSize
- }
+ text: qsTr("Server settings")
+ }
- // AwgTextField {
- // id: cookieReplyPacketJunkSizeTextField
- // enabled: false
+ AwgTextField {
+ id: portTextField
- // headerText: "S3 - Cookie Reply packet junk size"
- // textField.text: serverCookieReplyPacketJunkSize
- // }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- // AwgTextField {
- // id: transportPacketJunkSizeTextField
- // enabled: false
+ enabled: false
- // headerText: "S4 - Transport packet junk size"
- // textField.text: serverTransportPacketJunkSize
- // }
+ headerText: qsTr("Port")
+ textField.text: port
+ }
- AwgTextField {
- id: initPacketMagicHeaderTextField
- enabled: false
+ AwgTextField {
+ id: initPacketJunkSizeTextField
- headerText: "H1 - Init packet magic header"
- textField.text: serverInitPacketMagicHeader
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- AwgTextField {
- id: responsePacketMagicHeaderTextField
- enabled: false
+ enabled: false
- headerText: "H2 - Response packet magic header"
- textField.text: serverResponsePacketMagicHeader
- }
+ headerText: "S1 - Init packet junk size"
+ textField.text: serverInitPacketJunkSize
+ }
- AwgTextField {
- id: underloadPacketMagicHeaderTextField
- enabled: false
+ AwgTextField {
+ id: responsePacketJunkSizeTextField
- headerText: "H3 - Underload packet magic header"
- textField.text: serverUnderloadPacketMagicHeader
- }
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- AwgTextField {
- id: transportPacketMagicHeaderTextField
- enabled: false
+ enabled: false
- headerText: "H4 - Transport packet magic header"
- textField.text: serverTransportPacketMagicHeader
- }
+ headerText: "S2 - Response packet junk size"
+ textField.text: serverResponsePacketJunkSize
+ }
+ // AwgTextField {
+ // id: cookieReplyPacketJunkSizeTextField
+
+ // Layout.leftMargin: 16
+ // Layout.rightMargin: 16
+
+ // enabled: false
+
+ // headerText: "S3 - Cookie Reply packet junk size"
+ // textField.text: serverCookieReplyPacketJunkSize
+ // }
+
+ // AwgTextField {
+ // id: transportPacketJunkSizeTextField
+
+ // Layout.leftMargin: 16
+ // Layout.rightMargin: 16
+
+ // enabled: false
+
+ // headerText: "S4 - Transport packet junk size"
+ // textField.text: serverTransportPacketJunkSize
+ // }
+
+ AwgTextField {
+ id: initPacketMagicHeaderTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: false
+
+ headerText: "H1 - Init packet magic header"
+ textField.text: serverInitPacketMagicHeader
+ }
+
+ AwgTextField {
+ id: responsePacketMagicHeaderTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: false
+
+ headerText: "H2 - Response packet magic header"
+ textField.text: serverResponsePacketMagicHeader
+ }
+
+ AwgTextField {
+ id: underloadPacketMagicHeaderTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: false
+
+ headerText: "H3 - Underload packet magic header"
+ textField.text: serverUnderloadPacketMagicHeader
+ }
+
+ AwgTextField {
+ id: transportPacketMagicHeaderTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: false
+
+ headerText: "H4 - Transport packet magic header"
+ textField.text: serverTransportPacketMagicHeader
}
}
}
@@ -375,18 +423,17 @@ PageType {
anchors.rightMargin: 16
anchors.leftMargin: 16
- enabled: listview.currentItem.isSaveButtonEnabled
+ enabled: listView.currentItem.isSaveButtonEnabled
text: qsTr("Save")
onActiveFocusChanged: {
if(activeFocus) {
- listview.positionViewAtEnd()
+ listView.positionViewAtEnd()
}
}
clickedFunc: function() {
- forceActiveFocus()
var headerText = qsTr("Save settings?")
var descriptionText = qsTr("Only the settings for this device will be changed")
var yesButtonText = qsTr("Continue")
@@ -401,11 +448,9 @@ PageType {
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
InstallController.updateContainer(AwgConfigModel.getConfig())
}
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- saveButton.forceActiveFocus()
- }
- }
+
+ var noButtonFunction = function() {}
+
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
}
diff --git a/client/ui/qml/Pages2/PageProtocolAwgSettings.qml b/client/ui/qml/Pages2/PageProtocolAwgSettings.qml
index 699ae724..2140f740 100644
--- a/client/ui/qml/Pages2/PageProtocolAwgSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolAwgSettings.qml
@@ -19,334 +19,343 @@ import "../Components"
PageType {
id: root
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- ListView {
- id: listview
-
- property bool isFocusable: true
+ ListViewType {
+ id: listView
anchors.top: backButtonLayout.bottom
anchors.bottom: parent.bottom
-
- width: parent.width
-
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
- clip: true
+ anchors.left: parent.left
+ anchors.right: parent.right
model: AwgConfigModel
- delegate: Item {
+ delegate: ColumnLayout {
id: delegateItem
- implicitWidth: listview.width
- implicitHeight: col.implicitHeight
+
+ width: listView.width
property alias vpnAddressSubnetTextField: vpnAddressSubnetTextField
property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
- ColumnLayout {
- id: col
+ spacing: 0
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- anchors.leftMargin: 16
- anchors.rightMargin: 16
+ headerText: qsTr("AmneziaWG settings")
+ }
- spacing: 0
+ TextFieldWithHeaderType {
+ id: vpnAddressSubnetTextField
- BaseHeaderType {
- Layout.fillWidth: true
+ Layout.fillWidth: true
+ Layout.topMargin: 40
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- headerText: qsTr("AmneziaWG settings")
- }
+ enabled: delegateItem.isEnabled
- TextFieldWithHeaderType {
- id: vpnAddressSubnetTextField
+ headerText: qsTr("VPN address subnet")
+ textField.text: subnetAddress
- Layout.fillWidth: true
- Layout.topMargin: 40
-
- enabled: delegateItem.isEnabled
-
- headerText: qsTr("VPN address subnet")
- textField.text: subnetAddress
-
- textField.onEditingFinished: {
- if (textField.text !== subnetAddress) {
- subnetAddress = textField.text
- }
- }
-
- checkEmptyText: true
- }
-
- TextFieldWithHeaderType {
- id: portTextField
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- enabled: delegateItem.isEnabled
-
- headerText: qsTr("Port")
- textField.text: port
- textField.maximumLength: 5
- textField.validator: IntValidator { bottom: 1; top: 65535 }
-
- textField.onEditingFinished: {
- if (textField.text !== port) {
- port = textField.text
- }
- }
-
- checkEmptyText: true
- }
-
- AwgTextField {
- id: junkPacketCountTextField
- headerText: qsTr("Jc - Junk packet count")
- textField.text: serverJunkPacketCount
-
- textField.onEditingFinished: {
- if (textField.text !== serverJunkPacketCount) {
- serverJunkPacketCount = textField.text
- }
+ textField.onEditingFinished: {
+ if (textField.text !== subnetAddress) {
+ subnetAddress = textField.text
}
}
- AwgTextField {
- id: junkPacketMinSizeTextField
- headerText: qsTr("Jmin - Junk packet minimum size")
- textField.text: serverJunkPacketMinSize
+ checkEmptyText: true
+ }
- textField.onEditingFinished: {
- if (textField.text !== serverJunkPacketMinSize) {
- serverJunkPacketMinSize = textField.text
- }
+ TextFieldWithHeaderType {
+ id: portTextField
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: delegateItem.isEnabled
+
+ headerText: qsTr("Port")
+ textField.text: port
+ textField.maximumLength: 5
+ textField.validator: IntValidator { bottom: 1; top: 65535 }
+
+ textField.onEditingFinished: {
+ if (textField.text !== port) {
+ port = textField.text
}
}
- AwgTextField {
- id: junkPacketMaxSizeTextField
- headerText: qsTr("Jmax - Junk packet maximum size")
- textField.text: serverJunkPacketMaxSize
+ checkEmptyText: true
+ }
- textField.onEditingFinished: {
- if (textField.text !== serverJunkPacketMaxSize) {
- serverJunkPacketMaxSize = textField.text
- }
+ AwgTextField {
+ id: junkPacketCountTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("Jc - Junk packet count")
+ textField.text: serverJunkPacketCount
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverJunkPacketCount) {
+ serverJunkPacketCount = textField.text
+ }
+ }
+ }
+
+ AwgTextField {
+ id: junkPacketMinSizeTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("Jmin - Junk packet minimum size")
+ textField.text: serverJunkPacketMinSize
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverJunkPacketMinSize) {
+ serverJunkPacketMinSize = textField.text
+ }
+ }
+ }
+
+ AwgTextField {
+ id: junkPacketMaxSizeTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("Jmax - Junk packet maximum size")
+ textField.text: serverJunkPacketMaxSize
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverJunkPacketMaxSize) {
+ serverJunkPacketMaxSize = textField.text
+ }
+ }
+ }
+
+ AwgTextField {
+ id: initPacketJunkSizeTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("S1 - Init packet junk size")
+ textField.text: serverInitPacketJunkSize
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverInitPacketJunkSize) {
+ serverInitPacketJunkSize = textField.text
+ }
+ }
+ }
+
+ AwgTextField {
+ id: responsePacketJunkSizeTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("S2 - Response packet junk size")
+ textField.text: serverResponsePacketJunkSize
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverResponsePacketJunkSize) {
+ serverResponsePacketJunkSize = textField.text
+ }
+ }
+ }
+
+ // AwgTextField {
+ // id: cookieReplyPacketJunkSizeTextField
+
+ // Layout.leftMargin: 16
+ // Layout.rightMargin: 16
+
+ // headerText: qsTr("S3 - Cookie reply packet junk size")
+ // textField.text: serverCookieReplyPacketJunkSize
+
+ // textField.onEditingFinished: {
+ // if (textField.text !== serverCookieReplyPacketJunkSize) {
+ // serverCookieReplyPacketJunkSize = textField.text
+ // }
+ // }
+ // }
+
+ // AwgTextField {
+ // id: transportPacketJunkSizeTextField
+
+ // Layout.leftMargin: 16
+ // Layout.rightMargin: 16
+
+ // headerText: qsTr("S4 - Transport packet junk size")
+ // textField.text: serverTransportPacketJunkSize
+
+ // textField.onEditingFinished: {
+ // if (textField.text !== serverTransportPacketJunkSize) {
+ // serverTransportPacketJunkSize = textField.text
+ // }
+ // }
+ // }
+
+ AwgTextField {
+ id: initPacketMagicHeaderTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("H1 - Init packet magic header")
+ textField.text: serverInitPacketMagicHeader
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverInitPacketMagicHeader) {
+ serverInitPacketMagicHeader = textField.text
+ }
+ }
+ }
+
+ AwgTextField {
+ id: responsePacketMagicHeaderTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("H2 - Response packet magic header")
+ textField.text: serverResponsePacketMagicHeader
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverResponsePacketMagicHeader) {
+ serverResponsePacketMagicHeader = textField.text
+ }
+ }
+ }
+
+ AwgTextField {
+ id: underloadPacketMagicHeaderTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("H3 - Underload packet magic header")
+ textField.text: serverUnderloadPacketMagicHeader
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverUnderloadPacketMagicHeader) {
+ serverUnderloadPacketMagicHeader = textField.text
+ }
+ }
+ }
+
+ AwgTextField {
+ id: transportPacketMagicHeaderTextField
+
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("H4 - Transport packet magic header")
+ textField.text: serverTransportPacketMagicHeader
+
+ textField.onEditingFinished: {
+ if (textField.text !== serverTransportPacketMagicHeader) {
+ serverTransportPacketMagicHeader = textField.text
+ }
+ }
+ }
+
+ BasicButtonType {
+ id: saveRestartButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: underloadPacketMagicHeaderTextField.errorText === "" &&
+ transportPacketMagicHeaderTextField.errorText === "" &&
+ responsePacketMagicHeaderTextField.errorText === "" &&
+ initPacketMagicHeaderTextField.errorText === "" &&
+ responsePacketJunkSizeTextField.errorText === "" &&
+ // cookieReplyHeaderJunkTextField.errorText === "" &&
+ // transportHeaderJunkTextField.errorText === "" &&
+ initPacketJunkSizeTextField.errorText === "" &&
+ junkPacketMaxSizeTextField.errorText === "" &&
+ junkPacketMinSizeTextField.errorText === "" &&
+ junkPacketCountTextField.errorText === "" &&
+ portTextField.errorText === "" &&
+ vpnAddressSubnetTextField.errorText === ""
+
+ text: qsTr("Save")
+
+ onActiveFocusChanged: {
+ if(activeFocus) {
+ listView.positionViewAtEnd()
}
}
- AwgTextField {
- id: initPacketJunkSizeTextField
- headerText: qsTr("S1 - Init packet junk size")
- textField.text: serverInitPacketJunkSize
-
- textField.onEditingFinished: {
- if (textField.text !== serverInitPacketJunkSize) {
- serverInitPacketJunkSize = textField.text
+ clickedFunc: function() {
+ if (delegateItem.isEnabled) {
+ if (AwgConfigModel.isHeadersEqual(underloadPacketMagicHeaderTextField.textField.text,
+ transportPacketMagicHeaderTextField.textField.text,
+ responsePacketMagicHeaderTextField.textField.text,
+ initPacketMagicHeaderTextField.textField.text)) {
+ PageController.showErrorMessage(qsTr("The values of the H1-H4 fields must be unique"))
+ return
}
- }
- }
- AwgTextField {
- id: responsePacketJunkSizeTextField
- headerText: qsTr("S2 - Response packet junk size")
- textField.text: serverResponsePacketJunkSize
-
- textField.onEditingFinished: {
- if (textField.text !== serverResponsePacketJunkSize) {
- serverResponsePacketJunkSize = textField.text
- }
- }
- }
-
- // AwgTextField {
- // id: cookieReplyPacketJunkSizeTextField
- // headerText: qsTr("S3 - Cookie reply packet junk size")
- // textField.text: serverCookieReplyPacketJunkSize
-
- // textField.onEditingFinished: {
- // if (textField.text !== serverCookieReplyPacketJunkSize) {
- // serverCookieReplyPacketJunkSize = textField.text
- // }
- // }
- // }
-
- // AwgTextField {
- // id: transportPacketJunkSizeTextField
- // headerText: qsTr("S4 - Transport packet junk size")
- // textField.text: serverTransportPacketJunkSize
-
- // textField.onEditingFinished: {
- // if (textField.text !== serverTransportPacketJunkSize) {
- // serverTransportPacketJunkSize = textField.text
- // }
- // }
- // }
-
- AwgTextField {
- id: initPacketMagicHeaderTextField
- headerText: qsTr("H1 - Init packet magic header")
- textField.text: serverInitPacketMagicHeader
-
- textField.onEditingFinished: {
- if (textField.text !== serverInitPacketMagicHeader) {
- serverInitPacketMagicHeader = textField.text
- }
- }
- }
-
- AwgTextField {
- id: responsePacketMagicHeaderTextField
- headerText: qsTr("H2 - Response packet magic header")
- textField.text: serverResponsePacketMagicHeader
-
- textField.onEditingFinished: {
- if (textField.text !== serverResponsePacketMagicHeader) {
- serverResponsePacketMagicHeader = textField.text
- }
- }
- }
-
- AwgTextField {
- id: underloadPacketMagicHeaderTextField
- headerText: qsTr("H3 - Underload packet magic header")
- textField.text: serverUnderloadPacketMagicHeader
-
- textField.onEditingFinished: {
- if (textField.text !== serverUnderloadPacketMagicHeader) {
- serverUnderloadPacketMagicHeader = textField.text
- }
- }
- }
-
- AwgTextField {
- id: transportPacketMagicHeaderTextField
- headerText: qsTr("H4 - Transport packet magic header")
- textField.text: serverTransportPacketMagicHeader
-
- textField.onEditingFinished: {
- if (textField.text !== serverTransportPacketMagicHeader) {
- serverTransportPacketMagicHeader = textField.text
- }
- }
- }
-
-
- BasicButtonType {
- id: saveRestartButton
-
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 24
-
- enabled: underloadPacketMagicHeaderTextField.errorText === "" &&
- transportPacketMagicHeaderTextField.errorText === "" &&
- responsePacketMagicHeaderTextField.errorText === "" &&
- initPacketMagicHeaderTextField.errorText === "" &&
- responsePacketJunkSizeTextField.errorText === "" &&
- // cookieReplyHeaderJunkTextField.errorText === "" &&
- // transportHeaderJunkTextField.errorText === "" &&
- initPacketJunkSizeTextField.errorText === "" &&
- junkPacketMaxSizeTextField.errorText === "" &&
- junkPacketMinSizeTextField.errorText === "" &&
- junkPacketCountTextField.errorText === "" &&
- portTextField.errorText === "" &&
- vpnAddressSubnetTextField.errorText === ""
-
- text: qsTr("Save")
-
- onActiveFocusChanged: {
- if(activeFocus) {
- listview.positionViewAtEnd()
+ if (AwgConfigModel.isPacketSizeEqual(parseInt(initPacketJunkSizeTextField.textField.text),
+ parseInt(responsePacketJunkSizeTextField.textField.text))) {
+ PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)"))
+ return
}
+ // if (AwgConfigModel.isPacketSizeEqual(parseInt(initPacketJunkSizeTextField.textField.text),
+ // parseInt(responsePacketJunkSizeTextField.textField.text),
+ // parseInt(cookieReplyPacketJunkSizeTextField.textField.text),
+ // parseInt(transportPacketJunkSizeTextField.textField.text))) {
+ // PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) + S3 + cookie reply size (64) + S4 + transport packet size (32)"))
+ // return
+ // }
}
- clickedFunc: function() {
- forceActiveFocus()
+ var headerText = qsTr("Save settings?")
+ var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
- if (delegateItem.isEnabled) {
- if (AwgConfigModel.isHeadersEqual(underloadPacketMagicHeaderTextField.textField.text,
- transportPacketMagicHeaderTextField.textField.text,
- responsePacketMagicHeaderTextField.textField.text,
- initPacketMagicHeaderTextField.textField.text)) {
- PageController.showErrorMessage(qsTr("The values of the H1-H4 fields must be unique"))
- return
- }
-
- if (AwgConfigModel.isPacketSizeEqual(parseInt(initPacketJunkSizeTextField.textField.text),
- parseInt(responsePacketJunkSizeTextField.textField.text))) {
- PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)"))
- return
- }
- // if (AwgConfigModel.isPacketSizeEqual(parseInt(initPacketJunkSizeTextField.textField.text),
- // parseInt(responsePacketJunkSizeTextField.textField.text),
- // parseInt(cookieReplyPacketJunkSizeTextField.textField.text),
- // parseInt(transportPacketJunkSizeTextField.textField.text))) {
- // PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) + S3 + cookie reply size (64) + S4 + transport packet size (32)"))
- // return
- // }
+ var yesButtonFunction = function() {
+ if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
+ PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
+ return
}
- var headerText = qsTr("Save settings?")
- var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
- PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
- return
- }
-
- PageController.goToPage(PageEnum.PageSetupWizardInstalling);
- InstallController.updateContainer(AwgConfigModel.getConfig())
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- saveRestartButton.forceActiveFocus()
- }
- }
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ PageController.goToPage(PageEnum.PageSetupWizardInstalling);
+ InstallController.updateContainer(AwgConfigModel.getConfig())
}
+
+ var noButtonFunction = function() {}
+
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
}
}
diff --git a/client/ui/qml/Pages2/PageProtocolCloakSettings.qml b/client/ui/qml/Pages2/PageProtocolCloakSettings.qml
index 8e5129b0..51d4c9e2 100644
--- a/client/ui/qml/Pages2/PageProtocolCloakSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolCloakSettings.qml
@@ -16,212 +16,192 @@ import "../Components"
PageType {
id: root
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight
+ anchors.left: parent.left
+ anchors.right: parent.right
- Column {
- id: content
+ property int selectedIndex: 0
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ enabled: ServersModel.isProcessedServerHasWriteAccess()
- enabled: ServersModel.isProcessedServerHasWriteAccess()
+ header: ColumnLayout {
+ width: listView.width
- ListView {
- id: listview
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- property int selectedIndex: 0
+ headerText: qsTr("Cloak settings")
+ }
+ }
- width: parent.width
- height: listview.contentItem.height
+ model: CloakConfigModel
- clip: true
- reuseItems: true
+ delegate: ColumnLayout {
+ width: listView.width
- model: CloakConfigModel
+ property alias trafficFromField: trafficFromField
- delegate: Item {
- id: delegateItem
+ spacing: 0
- property alias trafficFromField: trafficFromField
- property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
+ TextFieldWithHeaderType {
+ id: trafficFromField
- implicitWidth: listview.width
- implicitHeight: col.implicitHeight
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- ColumnLayout {
- id: col
+ headerText: qsTr("Disguised as traffic from")
+ textField.text: site
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ textField.onEditingFinished: {
+ if (textField.text !== site) {
+ var tmpText = textField.text
+ tmpText = tmpText.toLocaleLowerCase()
- anchors.leftMargin: 16
- anchors.rightMargin: 16
-
- spacing: 0
-
- BaseHeaderType {
- Layout.fillWidth: true
- headerText: qsTr("Cloak settings")
+ var indexHttps = tmpText.indexOf("https://")
+ if (indexHttps === 0) {
+ tmpText = textField.text.substring(8)
+ } else {
+ site = textField.text
}
+ }
+ }
- TextFieldWithHeaderType {
- id: trafficFromField
+ checkEmptyText: true
+ }
- Layout.fillWidth: true
- Layout.topMargin: 32
+ TextFieldWithHeaderType {
+ id: portTextField
- enabled: delegateItem.isEnabled
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- headerText: qsTr("Disguised as traffic from")
- textField.text: site
+ headerText: qsTr("Port")
+ textField.text: port
+ textField.maximumLength: 5
+ textField.validator: IntValidator { bottom: 1; top: 65535 }
- textField.onEditingFinished: {
- if (textField.text !== site) {
- var tmpText = textField.text
- tmpText = tmpText.toLocaleLowerCase()
+ textField.onEditingFinished: {
+ if (textField.text !== port) {
+ port = textField.text
+ }
+ }
- var indexHttps = tmpText.indexOf("https://")
- if (indexHttps === 0) {
- tmpText = textField.text.substring(8)
- } else {
- site = textField.text
- }
- }
+ checkEmptyText: true
+ }
+
+ DropDownType {
+ id: cipherDropDown
+
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ descriptionText: qsTr("Cipher")
+ headerText: qsTr("Cipher")
+
+ drawerParent: root
+
+ listView: ListViewWithRadioButtonType {
+ id: cipherListView
+
+ rootWidth: root.width
+
+ model: ListModel {
+ ListElement { name : "chacha20-ietf-poly1305" }
+ ListElement { name : "xchacha20-ietf-poly1305" }
+ ListElement { name : "aes-256-gcm" }
+ ListElement { name : "aes-192-gcm" }
+ ListElement { name : "aes-128-gcm" }
+ }
+
+ clickedFunction: function() {
+ cipherDropDown.text = selectedText
+ cipher = cipherDropDown.text
+ cipherDropDown.closeTriggered()
+ }
+
+ Component.onCompleted: {
+ cipherDropDown.text = cipher
+
+ for (var i = 0; i < cipherListView.model.count; i++) {
+ if (cipherListView.model.get(i).name === cipherDropDown.text) {
+ selectedIndex = i
}
-
- checkEmptyText: true
- }
-
- TextFieldWithHeaderType {
- id: portTextField
-
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- enabled: delegateItem.isEnabled
-
- headerText: qsTr("Port")
- textField.text: port
- textField.maximumLength: 5
- textField.validator: IntValidator { bottom: 1; top: 65535 }
-
- textField.onEditingFinished: {
- if (textField.text !== port) {
- port = textField.text
- }
- }
-
- checkEmptyText: true
- }
-
- DropDownType {
- id: cipherDropDown
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- enabled: delegateItem.isEnabled
-
- descriptionText: qsTr("Cipher")
- headerText: qsTr("Cipher")
-
- drawerParent: root
-
- listView: ListViewWithRadioButtonType {
- id: cipherListView
-
- rootWidth: root.width
-
- model: ListModel {
- ListElement { name : "chacha20-ietf-poly1305" }
- ListElement { name : "xchacha20-ietf-poly1305" }
- ListElement { name : "aes-256-gcm" }
- ListElement { name : "aes-192-gcm" }
- ListElement { name : "aes-128-gcm" }
- }
-
- clickedFunction: function() {
- cipherDropDown.text = selectedText
- cipher = cipherDropDown.text
- cipherDropDown.closeTriggered()
- }
-
- Component.onCompleted: {
- cipherDropDown.text = cipher
-
- for (var i = 0; i < cipherListView.model.count; i++) {
- if (cipherListView.model.get(i).name === cipherDropDown.text) {
- selectedIndex = i
- }
- }
- }
- }
- }
-
- BasicButtonType {
- id: saveButton
-
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 24
-
- enabled: trafficFromField.errorText === "" &&
- portTextField.errorText === ""
-
- text: qsTr("Save")
-
- clickedFunc: function() {
- forceActiveFocus()
-
- var headerText = qsTr("Save settings?")
- var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
- PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
- return
- }
-
- PageController.goToPage(PageEnum.PageSetupWizardInstalling)
- InstallController.updateContainer(CloakConfigModel.getConfig())
- }
-
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- saveButton.forceActiveFocus()
- }
- }
-
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
-
- Keys.onEnterPressed: saveButton.clicked()
- Keys.onReturnPressed: saveButton.clicked()
}
}
}
}
+
+ BasicButtonType {
+ id: saveButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: trafficFromField.errorText === "" &&
+ portTextField.errorText === ""
+
+ text: qsTr("Save")
+
+ clickedFunc: function() {
+ forceActiveFocus()
+
+ var headerText = qsTr("Save settings?")
+ var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
+ PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
+ return
+ }
+
+ PageController.goToPage(PageEnum.PageSetupWizardInstalling)
+ InstallController.updateContainer(CloakConfigModel.getConfig())
+ }
+
+ var noButtonFunction = function() {
+ if (!GC.isMobile()) {
+ saveButton.forceActiveFocus()
+ }
+ }
+
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+
+ Keys.onEnterPressed: saveButton.clicked()
+ Keys.onReturnPressed: saveButton.clicked()
+ }
}
}
}
diff --git a/client/ui/qml/Pages2/PageProtocolRaw.qml b/client/ui/qml/Pages2/PageProtocolRaw.qml
index bba3eafe..b90af6f6 100644
--- a/client/ui/qml/Pages2/PageProtocolRaw.qml
+++ b/client/ui/qml/Pages2/PageProtocolRaw.qml
@@ -19,164 +19,154 @@ import "../Components"
PageType {
id: root
- ColumnLayout {
- id: header
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
- }
-
- BaseHeaderType {
- Layout.fillWidth: true
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- headerText: ContainersModel.getProcessedContainerName() + qsTr(" settings")
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: header.bottom
- anchors.left: parent.left
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
anchors.right: parent.right
- contentHeight: content.height
+ anchors.left: parent.left
- Column {
- id: content
+ header: ColumnLayout {
+ width: listView.width
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 32
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 16
- ListView {
- id: listView
- width: parent.width
- height: contentItem.height
- clip: true
- interactive: false
- model: ProtocolsModel
+ headerText: ContainersModel.getProcessedContainerName() + qsTr(" settings")
+ }
+ }
- activeFocusOnTab: true
- focus: true
+ model: ProtocolsModel
- delegate: Item {
- implicitWidth: parent.width
- implicitHeight: delegateContent.implicitHeight
+ delegate: ColumnLayout {
+ width: listView.width
- property alias focusItem: button
+ LabelWithButtonType {
+ id: button
- ColumnLayout {
- id: delegateContent
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- anchors.fill: parent
+ text: qsTr("Show connection options")
- LabelWithButtonType {
- id: button
+ clickedFunction: function() {
+ configContentDrawer.openTriggered()
+ }
- Layout.fillWidth: true
+ MouseArea {
+ anchors.fill: button
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
+ }
- text: qsTr("Show connection options")
+ DividerType {}
- clickedFunction: function() {
- configContentDrawer.openTriggered()
- }
+ DrawerType2 {
+ id: configContentDrawer
- MouseArea {
- anchors.fill: button
- cursorShape: Qt.PointingHandCursor
- enabled: false
+ expandedHeight: root.height * 0.9
+
+ parent: root
+ anchors.fill: parent
+
+ expandedStateContent: Item {
+ implicitHeight: configContentDrawer.expandedHeight
+
+ BackButtonType {
+ id: drawerBackButton
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 16
+
+ backButtonFunction: function() {
+ configContentDrawer.closeTriggered()
+ }
+ }
+
+ ListViewType {
+ id: drawerListView
+
+ anchors.top: drawerBackButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+
+ header: ColumnLayout {
+ width: drawerListView.width
+
+ Header2Type {
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("Connection options %1").arg(protocolName)
}
}
- DividerType {}
+ model: 1 // fake model to force the ListView to be created without a model
- DrawerType2 {
- id: configContentDrawer
+ delegate: ColumnLayout {
+ width: drawerListView.width
- expandedHeight: root.height * 0.9
+ TextArea {
+ id: configText
- parent: root
- anchors.fill: parent
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- expandedStateContent: Item {
- implicitHeight: configContentDrawer.expandedHeight
+ padding: 0
+ height: 24
- BackButtonType {
- id: backButton1
+ color: AmneziaStyle.color.paleGray
+ selectionColor: AmneziaStyle.color.richBrown
+ selectedTextColor: AmneziaStyle.color.paleGray
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 16
+ font.pixelSize: 16
+ font.weight: Font.Medium
+ font.family: "PT Root UI VF"
- backButtonFunction: function() {
- configContentDrawer.closeTriggered()
- }
- }
+ text: rawConfig
- FlickableType {
- anchors.top: backButton1.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- contentHeight: configContent.implicitHeight + configContent.anchors.topMargin + configContent.anchors.bottomMargin
+ wrapMode: Text.Wrap
- ColumnLayout {
- id: configContent
-
- anchors.fill: parent
- anchors.rightMargin: 16
- anchors.leftMargin: 16
-
- Header2Type {
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- headerText: qsTr("Connection options %1").arg(protocolName)
- }
-
- TextArea {
- id: configText
-
- Layout.fillWidth: true
- Layout.topMargin: 16
- Layout.bottomMargin: 16
-
- padding: 0
- leftPadding: 0
- height: 24
-
- color: AmneziaStyle.color.paleGray
- selectionColor: AmneziaStyle.color.richBrown
- selectedTextColor: AmneziaStyle.color.paleGray
-
- font.pixelSize: 16
- font.weight: Font.Medium
- font.family: "PT Root UI VF"
-
- text: rawConfig
-
- wrapMode: Text.Wrap
-
- background: Rectangle {
- color: AmneziaStyle.color.transparent
- }
- }
- }
+ background: Rectangle {
+ color: AmneziaStyle.color.transparent
}
}
}
}
}
}
+ }
+
+ footer: ColumnLayout {
+ width: listView.width
LabelWithButtonType {
id: removeButton
@@ -198,11 +188,7 @@ PageType {
PageController.goToPage(PageEnum.PageDeinstalling)
InstallController.removeProcessedContainer()
}
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- focusItem.forceActiveFocus()
- }
- }
+ var noButtonFunction = function() {}
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
diff --git a/client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml b/client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml
index 92df3ec7..4d587539 100644
--- a/client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml
@@ -16,179 +16,158 @@ import "../Components"
PageType {
id: root
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight
+ anchors.right: parent.right
+ anchors.left: parent.left
- Column {
- id: content
+ enabled: ServersModel.isProcessedServerHasWriteAccess()
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ model: ShadowSocksConfigModel
- enabled: ServersModel.isProcessedServerHasWriteAccess()
+ delegate: ColumnLayout {
+ width: listView.width
- ListView {
- id: listview
+ spacing: 0
- width: parent.width
- height: listview.contentItem.height
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- clip: true
- interactive: false
+ headerText: qsTr("Shadowsocks settings")
+ }
- model: ShadowSocksConfigModel
+ TextFieldWithHeaderType {
+ id: portTextField
- delegate: Item {
- id: delegateItem
+ Layout.fillWidth: true
+ Layout.topMargin: 40
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
+ enabled: listView.enabled
- implicitWidth: listview.width
- implicitHeight: col.implicitHeight
+ headerText: qsTr("Port")
+ textField.text: port
+ textField.maximumLength: 5
+ textField.validator: IntValidator { bottom: 1; top: 65535 }
- ColumnLayout {
- id: col
+ textField.onEditingFinished: {
+ if (textField.text !== port) {
+ port = textField.text
+ }
+ }
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ checkEmptyText: true
+ }
- anchors.leftMargin: 16
- anchors.rightMargin: 16
+ DropDownType {
+ id: cipherDropDown
- spacing: 0
+ Layout.fillWidth: true
+ Layout.topMargin: 20
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- BaseHeaderType {
- Layout.fillWidth: true
- headerText: qsTr("Shadowsocks settings")
- }
+ enabled: listView.enabled
- TextFieldWithHeaderType {
- id: portTextField
+ descriptionText: qsTr("Cipher")
+ headerText: qsTr("Cipher")
- Layout.fillWidth: true
- Layout.topMargin: 40
+ drawerParent: root
- enabled: delegateItem.isEnabled
+ listView: ListViewWithRadioButtonType {
- headerText: qsTr("Port")
- textField.text: port
- textField.maximumLength: 5
- textField.validator: IntValidator { bottom: 1; top: 65535 }
+ id: cipherListView
- textField.onEditingFinished: {
- if (textField.text !== port) {
- port = textField.text
- }
+ rootWidth: root.width
+
+ model: ListModel {
+ ListElement { name : "chacha20-ietf-poly1305" }
+ ListElement { name : "xchacha20-ietf-poly1305" }
+ ListElement { name : "aes-256-gcm" }
+ ListElement { name : "aes-192-gcm" }
+ ListElement { name : "aes-128-gcm" }
+ }
+
+ clickedFunction: function() {
+ cipherDropDown.text = selectedText
+ cipher = cipherDropDown.text
+ cipherDropDown.closeTriggered()
+ }
+
+ Component.onCompleted: {
+ cipherDropDown.text = cipher
+
+ for (var i = 0; i < cipherListView.model.count; i++) {
+ if (cipherListView.model.get(i).name === cipherDropDown.text) {
+ currentIndex = i
}
-
- checkEmptyText: true
- }
-
- DropDownType {
- id: cipherDropDown
- Layout.fillWidth: true
- Layout.topMargin: 20
-
- enabled: delegateItem.isEnabled
-
- descriptionText: qsTr("Cipher")
- headerText: qsTr("Cipher")
-
- drawerParent: root
-
- listView: ListViewWithRadioButtonType {
-
- id: cipherListView
-
- rootWidth: root.width
-
- model: ListModel {
- ListElement { name : "chacha20-ietf-poly1305" }
- ListElement { name : "xchacha20-ietf-poly1305" }
- ListElement { name : "aes-256-gcm" }
- ListElement { name : "aes-192-gcm" }
- ListElement { name : "aes-128-gcm" }
- }
-
- clickedFunction: function() {
- cipherDropDown.text = selectedText
- cipher = cipherDropDown.text
- cipherDropDown.closeTriggered()
- }
-
- Component.onCompleted: {
- cipherDropDown.text = cipher
-
- for (var i = 0; i < cipherListView.model.count; i++) {
- if (cipherListView.model.get(i).name === cipherDropDown.text) {
- currentIndex = i
- }
- }
- }
- }
- }
-
- BasicButtonType {
- id: saveButton
-
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 24
-
- enabled: portTextField.errorText === ""
-
- text: qsTr("Save")
-
- clickedFunc: function() {
- forceActiveFocus()
-
- var headerText = qsTr("Save settings?")
- var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
- PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
- return
- }
-
- PageController.goToPage(PageEnum.PageSetupWizardInstalling);
- InstallController.updateContainer(ShadowSocksConfigModel.getConfig())
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- saveButton.forceActiveFocus()
- }
- }
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
-
- Keys.onEnterPressed: saveButton.clicked()
- Keys.onReturnPressed: saveButton.clicked()
}
}
}
}
+
+ BasicButtonType {
+ id: saveButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: portTextField.errorText === ""
+
+ text: qsTr("Save")
+
+ clickedFunc: function() {
+ forceActiveFocus()
+
+ var headerText = qsTr("Save settings?")
+ var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
+ PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
+ return
+ }
+
+ PageController.goToPage(PageEnum.PageSetupWizardInstalling);
+ InstallController.updateContainer(ShadowSocksConfigModel.getConfig())
+ }
+ var noButtonFunction = function() {
+ if (!GC.isMobile()) {
+ saveButton.forceActiveFocus()
+ }
+ }
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+
+ Keys.onEnterPressed: saveButton.clicked()
+ Keys.onReturnPressed: saveButton.clicked()
+ }
}
}
}
diff --git a/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml b/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml
index 96ec1dc6..ef2490c7 100644
--- a/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml
@@ -16,160 +16,124 @@ import "../Components"
PageType {
id: root
- Item {
- id: focusItem
- onFocusChanged: {
- if (activeFocus) {
- fl.ensureVisible(focusItem)
- }
- }
- KeyNavigation.tab: backButton
- }
-
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
- KeyNavigation.tab: listview.currentItem.mtuTextField.textField
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight + saveButton.implicitHeight + saveButton.anchors.bottomMargin + saveButton.anchors.topMargin
+ anchors.right: parent.right
+ anchors.left: parent.left
- Column {
- id: content
+ model: WireGuardConfigModel
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ delegate: ColumnLayout {
+ width: listView.width
- ListView {
- id: listview
+ property alias mtuTextField: mtuTextField
+ property bool isSaveButtonEnabled: mtuTextField.errorText === ""
- width: parent.width
- height: listview.contentItem.height
+ spacing: 0
- clip: true
- interactive: false
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- model: WireGuardConfigModel
+ headerText: qsTr("WG settings")
+ }
- delegate: Item {
- id: delegateItem
- implicitWidth: listview.width
- implicitHeight: col.implicitHeight
+ TextFieldWithHeaderType {
+ id: mtuTextField
+ Layout.fillWidth: true
+ Layout.topMargin: 40
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- property alias mtuTextField: mtuTextField
- property bool isSaveButtonEnabled: mtuTextField.errorText === ""
+ headerText: qsTr("MTU")
+ textField.text: clientMtu
+ textField.validator: IntValidator { bottom: 576; top: 65535 }
- ColumnLayout {
- id: col
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- anchors.leftMargin: 16
- anchors.rightMargin: 16
-
- spacing: 0
-
- BaseHeaderType {
- Layout.fillWidth: true
-
- headerText: qsTr("WG settings")
- }
-
- TextFieldWithHeaderType {
- id: mtuTextField
- Layout.fillWidth: true
- Layout.topMargin: 40
-
- headerText: qsTr("MTU")
- textField.text: clientMtu
- textField.validator: IntValidator { bottom: 576; top: 65535 }
-
- textField.onEditingFinished: {
- if (textField.text !== clientMtu) {
- clientMtu = textField.text
- }
- }
- checkEmptyText: true
- KeyNavigation.tab: saveButton
- }
-
- Header2TextType {
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- text: qsTr("Server settings")
- }
-
- TextFieldWithHeaderType {
- id: portTextField
- Layout.fillWidth: true
- Layout.topMargin: 8
-
- enabled: false
-
- headerText: qsTr("Port")
- textField.text: port
- }
- }
+ textField.onEditingFinished: {
+ if (textField.text !== clientMtu) {
+ clientMtu = textField.text
+ }
}
+ checkEmptyText: true
+ }
+
+ Header2TextType {
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Server settings")
+ }
+
+ TextFieldWithHeaderType {
+ id: portTextField
+ Layout.fillWidth: true
+ Layout.topMargin: 8
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: false
+
+ headerText: qsTr("Port")
+ textField.text: port
}
}
- }
- BasicButtonType {
- id: saveButton
+ footer: ColumnLayout {
+ width: listView.width
- anchors.right: root.right
- anchors.left: root.left
- anchors.bottom: root.bottom
+ BasicButtonType {
+ id: saveButton
- anchors.topMargin: 24
- anchors.bottomMargin: 24
- anchors.rightMargin: 16
- anchors.leftMargin: 16
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
- enabled: listview.currentItem.isSaveButtonEnabled
+ enabled: listView.currentItem.isSaveButtonEnabled
- text: qsTr("Save")
+ text: qsTr("Save")
- clickedFunc: function() {
- forceActiveFocus()
- var headerText = qsTr("Save settings?")
- var descriptionText = qsTr("Only the settings for this device will be changed")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
+ clickedFunc: function() {
+ var headerText = qsTr("Save settings?")
+ var descriptionText = qsTr("Only the settings for this device will be changed")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
- var yesButtonFunction = function() {
- if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
- PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
- return
- }
+ var yesButtonFunction = function() {
+ if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
+ PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
+ return
+ }
- PageController.goToPage(PageEnum.PageSetupWizardInstalling);
- InstallController.updateContainer(WireGuardConfigModel.getConfig())
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- saveButton.forceActiveFocus()
+ PageController.goToPage(PageEnum.PageSetupWizardInstalling);
+ InstallController.updateContainer(WireGuardConfigModel.getConfig())
+ }
+ var noButtonFunction = function() {}
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
}
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
}
}
diff --git a/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml b/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml
index 3122267f..d8ea1d95 100644
--- a/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml
@@ -16,153 +16,134 @@ import "../Components"
PageType {
id: root
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight
+ anchors.right: parent.right
+ anchors.left: parent.left
- Column {
- id: content
+ enabled: ServersModel.isProcessedServerHasWriteAccess()
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ model: WireGuardConfigModel
- enabled: ServersModel.isProcessedServerHasWriteAccess()
+ delegate: ColumnLayout {
+ width: listView.width
- ListView {
- id: listview
+ property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
- width: parent.width
- height: listview.contentItem.height
+ spacing: 0
- clip: true
- interactive: false
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- model: WireGuardConfigModel
+ headerText: qsTr("WG settings")
+ }
- delegate: Item {
- id: delegateItem
+ TextFieldWithHeaderType {
+ id: vpnAddressSubnetTextField
- property alias focusItemId: vpnAddressSubnetTextField
- property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
+ Layout.fillWidth: true
+ Layout.topMargin: 40
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- implicitWidth: listview.width
- implicitHeight: col.implicitHeight
+ enabled: delegateItem.isEnabled
- ColumnLayout {
- id: col
+ headerText: qsTr("VPN address subnet")
+ textField.text: subnetAddress
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- anchors.leftMargin: 16
- anchors.rightMargin: 16
-
- spacing: 0
-
- BaseHeaderType {
- Layout.fillWidth: true
- headerText: qsTr("WG settings")
- }
-
- TextFieldWithHeaderType {
- id: vpnAddressSubnetTextField
- Layout.fillWidth: true
- Layout.topMargin: 40
-
- enabled: delegateItem.isEnabled
-
- headerText: qsTr("VPN address subnet")
- textField.text: subnetAddress
-
- textField.onEditingFinished: {
- if (textField.text !== subnetAddress) {
- subnetAddress = textField.text
- }
- }
-
- checkEmptyText: true
- }
-
- TextFieldWithHeaderType {
- id: portTextField
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- enabled: delegateItem.isEnabled
-
- headerText: qsTr("Port")
- textField.text: port
- textField.maximumLength: 5
- textField.validator: IntValidator { bottom: 1; top: 65535 }
-
- textField.onEditingFinished: {
- if (textField.text !== port) {
- port = textField.text
- }
- }
-
- checkEmptyText: true
- }
-
- BasicButtonType {
- id: saveButton
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 24
-
- enabled: portTextField.errorText === "" &&
- vpnAddressSubnetTextField.errorText === ""
-
- text: qsTr("Save")
-
- onClicked: function() {
- forceActiveFocus()
-
- var headerText = qsTr("Save settings?")
- var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
- PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
- return
- }
-
- PageController.goToPage(PageEnum.PageSetupWizardInstalling);
- InstallController.updateContainer(WireGuardConfigModel.getConfig())
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- saveButton.forceActiveFocus()
- }
- }
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
-
- Keys.onEnterPressed: this.clicked()
- Keys.onReturnPressed: this.clicked()
- }
+ textField.onEditingFinished: {
+ if (textField.text !== subnetAddress) {
+ subnetAddress = textField.text
}
}
+
+ checkEmptyText: true
+ }
+
+ TextFieldWithHeaderType {
+ id: portTextField
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: delegateItem.isEnabled
+
+ headerText: qsTr("Port")
+ textField.text: port
+ textField.maximumLength: 5
+ textField.validator: IntValidator { bottom: 1; top: 65535 }
+
+ textField.onEditingFinished: {
+ if (textField.text !== port) {
+ port = textField.text
+ }
+ }
+
+ checkEmptyText: true
+ }
+
+ BasicButtonType {
+ id: saveButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: portTextField.errorText === "" &&
+ vpnAddressSubnetTextField.errorText === ""
+
+ text: qsTr("Save")
+
+ onClicked: function() {
+ forceActiveFocus()
+
+ var headerText = qsTr("Save settings?")
+ var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
+ PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
+ return
+ }
+
+ PageController.goToPage(PageEnum.PageSetupWizardInstalling);
+ InstallController.updateContainer(WireGuardConfigModel.getConfig())
+ }
+ var noButtonFunction = function() {
+ if (!GC.isMobile()) {
+ saveButton.forceActiveFocus()
+ }
+ }
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+
+ Keys.onEnterPressed: saveButton.clicked()
+ Keys.onReturnPressed: saveButton.clicked()
}
}
}
diff --git a/client/ui/qml/Pages2/PageProtocolXraySettings.qml b/client/ui/qml/Pages2/PageProtocolXraySettings.qml
index 0bcd14de..8de36035 100644
--- a/client/ui/qml/Pages2/PageProtocolXraySettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolXraySettings.qml
@@ -17,163 +17,141 @@ import "../Components"
PageType {
id: root
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
- }
- }
-
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
- anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight
-
- Column {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- enabled: ServersModel.isProcessedServerHasWriteAccess()
-
- ListView {
- id: listview
-
- width: parent.width
- height: listview.contentItem.height
-
- clip: true
- interactive: false
-
- model: XrayConfigModel
-
- delegate: Item {
- id: delegateItem
-
- property alias focusItemId: textFieldWithHeaderType.textField
- property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
-
- implicitWidth: listview.width
- implicitHeight: col.implicitHeight
-
- ColumnLayout {
- id: col
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- anchors.leftMargin: 16
- anchors.rightMargin: 16
-
- spacing: 0
-
- BaseHeaderType {
- Layout.fillWidth: true
- headerText: qsTr("XRay settings")
- }
-
- TextFieldWithHeaderType {
- id: textFieldWithHeaderType
- Layout.fillWidth: true
- Layout.topMargin: 32
-
- enabled: delegateItem.isEnabled
-
- headerText: qsTr("Disguised as traffic from")
- textField.text: site
-
- textField.onEditingFinished: {
- if (textField.text !== site) {
- var tmpText = textField.text
- tmpText = tmpText.toLocaleLowerCase()
-
- if (tmpText.startsWith("https://")) {
- tmpText = textField.text.substring(8)
- site = tmpText
- } else {
- site = textField.text
- }
- }
- }
-
- checkEmptyText: true
- }
-
- TextFieldWithHeaderType {
- id: portTextField
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- enabled: delegateItem.isEnabled
-
- headerText: qsTr("Port")
- textField.text: port
- textField.maximumLength: 5
- textField.validator: IntValidator { bottom: 1; top: 65535 }
-
- textField.onEditingFinished: {
- if (textField.text !== port) {
- port = textField.text
- }
- }
-
- checkEmptyText: true
- }
-
- BasicButtonType {
- id: saveButton
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 24
-
- enabled: portTextField.errorText === ""
-
- text: qsTr("Save")
-
- onClicked: function() {
- forceActiveFocus()
-
- var headerText = qsTr("Save settings?")
- var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
- PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
- return
- }
-
- PageController.goToPage(PageEnum.PageSetupWizardInstalling);
- InstallController.updateContainer(XrayConfigModel.getConfig())
- //focusItem.forceActiveFocus()
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- saveButton.forceActiveFocus()
- }
- }
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
-
- Keys.onEnterPressed: saveButton.clicked()
- Keys.onReturnPressed: saveButton.clicked()
- }
- }
- }
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
}
}
}
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ enabled: ServersModel.isProcessedServerHasWriteAccess()
+ model: XrayConfigModel
+
+ delegate: ColumnLayout {
+ width: listView.width
+
+ property alias focusItemId: textFieldWithHeaderType.textField
+
+ spacing: 0
+
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ headerText: qsTr("XRay settings")
+ }
+
+ TextFieldWithHeaderType {
+ id: textFieldWithHeaderType
+
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: listView.enabled
+
+ headerText: qsTr("Disguised as traffic from")
+ textField.text: site
+
+ textField.onEditingFinished: {
+ if (textField.text !== site) {
+ var tmpText = textField.text
+ tmpText = tmpText.toLocaleLowerCase()
+
+ if (tmpText.startsWith("https://")) {
+ tmpText = textField.text.substring(8)
+ site = tmpText
+ } else {
+ site = textField.text
+ }
+ }
+ }
+
+ checkEmptyText: true
+ }
+
+ TextFieldWithHeaderType {
+ id: portTextField
+
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: listView.enabled
+
+ headerText: qsTr("Port")
+ textField.text: port
+ textField.maximumLength: 5
+ textField.validator: IntValidator { bottom: 1; top: 65535 }
+
+ textField.onEditingFinished: {
+ if (textField.text !== port) {
+ port = textField.text
+ }
+ }
+
+ checkEmptyText: true
+ }
+
+ BasicButtonType {
+ id: saveButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ enabled: portTextField.errorText === ""
+
+ text: qsTr("Save")
+
+ onClicked: function() {
+ forceActiveFocus()
+
+ var headerText = qsTr("Save settings?")
+ var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
+ PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
+ return
+ }
+
+ PageController.goToPage(PageEnum.PageSetupWizardInstalling);
+ InstallController.updateContainer(XrayConfigModel.getConfig())
+ }
+ var noButtonFunction = function() {
+ if (!GC.isMobile()) {
+ saveButton.forceActiveFocus()
+ }
+ }
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+
+ Keys.onEnterPressed: saveButton.clicked()
+ Keys.onReturnPressed: saveButton.clicked()
+ }
+ }
+ }
}
diff --git a/client/ui/qml/Pages2/PageServiceDnsSettings.qml b/client/ui/qml/Pages2/PageServiceDnsSettings.qml
index d534f991..442dc544 100644
--- a/client/ui/qml/Pages2/PageServiceDnsSettings.qml
+++ b/client/ui/qml/Pages2/PageServiceDnsSettings.qml
@@ -16,50 +16,53 @@ import "../Components"
PageType {
id: root
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
-
- BackButtonType {
- id: backButton
+
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight
+ anchors.right: parent.right
+ anchors.left: parent.left
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ header: ColumnLayout {
+ width: listView.width
BaseHeaderType {
- id: header
-
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
+ Layout.bottomMargin: 24
headerText: "AmneziaDNS"
descriptionText: qsTr("A DNS service is installed on your server, and it is only accessible via VPN.\n") +
qsTr("The DNS address is the same as the address of your server. You can configure DNS in the settings, under the connections tab.")
}
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+
+ delegate: ColumnLayout {
+ width: listView.width
LabelWithButtonType {
- id: removeButton
-
- Layout.topMargin: 24
- width: parent.width
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
textColor: AmneziaStyle.color.vibrantRed
@@ -71,19 +74,14 @@ PageType {
var yesButtonFunction = function() {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
- && SettingsController.isAmneziaDnsEnabled()) {
+ && SettingsController.isAmneziaDnsEnabled()) {
PageController.showNotificationMessage(qsTr("Cannot remove AmneziaDNS from running server"))
- } else
- {
+ } else {
PageController.goToPage(PageEnum.PageDeinstalling)
InstallController.removeProcessedContainer()
}
}
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- removeButton.rightButton.forceActiveFocus()
- }
- }
+ var noButtonFunction = function() {}
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
diff --git a/client/ui/qml/Pages2/PageServiceSftpSettings.qml b/client/ui/qml/Pages2/PageServiceSftpSettings.qml
index b58cb2e0..9fe0bac5 100644
--- a/client/ui/qml/Pages2/PageServiceSftpSettings.qml
+++ b/client/ui/qml/Pages2/PageServiceSftpSettings.qml
@@ -24,258 +24,215 @@ PageType {
}
}
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight
+ anchors.right: parent.right
+ anchors.left: parent.left
- Column {
- id: content
+ enabled: ServersModel.isProcessedServerHasWriteAccess()
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ model: SftpConfigModel
- enabled: ServersModel.isProcessedServerHasWriteAccess()
+ delegate: ColumnLayout {
+ width: listView.width
- ListView {
- id: listview
+ spacing: 0
- width: parent.width
- height: listview.contentItem.height
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- clip: true
- interactive: false
+ headerText: qsTr("SFTP settings")
+ }
- model: SftpConfigModel
+ LabelWithButtonType {
+ id: hostLabel
- onFocusChanged: {
- if (focus) {
- listview.currentItem.listViewFocusItem.forceActiveFocus()
- }
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Host")
+ descriptionText: ServersModel.getProcessedServerData("hostName")
+
+ descriptionOnTop: true
+
+ rightImageSource: "qrc:/images/controls/copy.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ clickedFunction: function() {
+ GC.copyToClipBoard(descriptionText)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ LabelWithButtonType {
+ id: portLabel
+
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Port")
+ descriptionText: port
+
+ descriptionOnTop: true
+
+ rightImageSource: "qrc:/images/controls/copy.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ clickedFunction: function() {
+ GC.copyToClipBoard(descriptionText)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ LabelWithButtonType {
+ id: usernameLabel
+
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("User name")
+ descriptionText: username
+
+ descriptionOnTop: true
+
+ rightImageSource: "qrc:/images/controls/copy.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ clickedFunction: function() {
+ GC.copyToClipBoard(descriptionText)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ LabelWithButtonType {
+ id: passwordLabel
+
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Password")
+ descriptionText: password
+
+ descriptionOnTop: true
+
+ rightImageSource: "qrc:/images/controls/copy.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ buttonImageSource: hideDescription ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg"
+
+ clickedFunction: function() {
+ GC.copyToClipBoard(descriptionText)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ BasicButtonType {
+ id: mountButton
+
+ visible: !GC.isMobile()
+
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ defaultColor: AmneziaStyle.color.transparent
+ hoveredColor: AmneziaStyle.color.translucentWhite
+ pressedColor: AmneziaStyle.color.sheerWhite
+ disabledColor: AmneziaStyle.color.mutedGray
+ textColor: AmneziaStyle.color.paleGray
+ borderWidth: 1
+
+ text: qsTr("Mount folder on device")
+
+ clickedFunc: function() {
+ PageController.showBusyIndicator(true)
+ InstallController.mountSftpDrive(port, password, username)
+ PageController.showBusyIndicator(false)
+ }
+ }
+
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ readonly property string windowsFirstLink: "WinFsp"
+ readonly property string windowsSecondLink: "SSHFS-Win"
+
+ readonly property string macosFirstLink: "macFUSE"
+ readonly property string macosSecondLink: "SSHFS"
+
+ onLinkActivated: function(link) {
+ Qt.openUrlExternally(link)
+ }
+ textFormat: Text.RichText
+ text: {
+ var str = qsTr("In order to mount remote SFTP folder as local drive, perform following steps:
")
+ if (Qt.platform.os === "windows") {
+ str += qsTr("
1. Install the latest version of ") + windowsFirstLink + "\n"
+ str += qsTr("
2. Install the latest version of ") + windowsSecondLink + "\n"
+ } else if (Qt.platform.os === "osx") {
+ str += qsTr("
1. Install the latest version of ") + macosFirstLink + "\n"
+ str += qsTr("
2. Install the latest version of ") + macosSecondLink + "\n"
+ } else if (Qt.platform.os === "linux") {
+ return ""
+ } else return ""
+
+ return str
}
- delegate: Item {
- implicitWidth: listview.width
- implicitHeight: col.implicitHeight
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.NoButton
+ cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
+ }
+ }
- property alias listViewFocusItem: hostLabel.rightButton
+ BasicButtonType {
+ id: detailedInstructionsButton
- ColumnLayout {
- id: col
+ Layout.topMargin: 16
+ Layout.bottomMargin: 16
+ Layout.leftMargin: 8
+ implicitHeight: 32
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ defaultColor: AmneziaStyle.color.transparent
+ hoveredColor: AmneziaStyle.color.translucentWhite
+ pressedColor: AmneziaStyle.color.sheerWhite
+ disabledColor: AmneziaStyle.color.mutedGray
+ textColor: AmneziaStyle.color.goldenApricot
- spacing: 0
+ text: qsTr("Detailed instructions")
- BaseHeaderType {
- Layout.fillWidth: true
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- headerText: qsTr("SFTP settings")
- }
-
- LabelWithButtonType {
- id: hostLabel
- Layout.fillWidth: true
- Layout.topMargin: 32
-
- parentFlickable: fl
-
- text: qsTr("Host")
- descriptionText: ServersModel.getProcessedServerData("hostName")
-
- descriptionOnTop: true
-
- rightImageSource: "qrc:/images/controls/copy.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- clickedFunction: function() {
- GC.copyToClipBoard(descriptionText)
- PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
- }
- }
- }
-
- LabelWithButtonType {
- id: portLabel
- Layout.fillWidth: true
-
- text: qsTr("Port")
- descriptionText: port
-
- descriptionOnTop: true
-
- parentFlickable: fl
-
- rightImageSource: "qrc:/images/controls/copy.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- clickedFunction: function() {
- GC.copyToClipBoard(descriptionText)
- PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
- }
- }
- }
-
- LabelWithButtonType {
- id: usernameLabel
- Layout.fillWidth: true
-
- text: qsTr("User name")
- descriptionText: username
-
- descriptionOnTop: true
-
- parentFlickable: fl
-
- rightImageSource: "qrc:/images/controls/copy.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- clickedFunction: function() {
- GC.copyToClipBoard(descriptionText)
- PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
- }
- }
- }
-
- LabelWithButtonType {
- id: passwordLabel
- Layout.fillWidth: true
-
- text: qsTr("Password")
- descriptionText: password
-
- descriptionOnTop: true
-
- parentFlickable: fl
-
- rightImageSource: "qrc:/images/controls/copy.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- buttonImageSource: hideDescription ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg"
-
- clickedFunction: function() {
- GC.copyToClipBoard(descriptionText)
- PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
- }
- }
- }
-
- BasicButtonType {
- id: mountButton
- visible: !GC.isMobile()
-
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 24
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- defaultColor: AmneziaStyle.color.transparent
- hoveredColor: AmneziaStyle.color.translucentWhite
- pressedColor: AmneziaStyle.color.sheerWhite
- disabledColor: AmneziaStyle.color.mutedGray
- textColor: AmneziaStyle.color.paleGray
- borderWidth: 1
-
- parentFlickable: fl
-
- text: qsTr("Mount folder on device")
-
- clickedFunc: function() {
- PageController.showBusyIndicator(true)
- InstallController.mountSftpDrive(port, password, username)
- PageController.showBusyIndicator(false)
- }
- }
-
- ParagraphTextType {
- Layout.fillWidth: true
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- readonly property string windowsFirstLink: "WinFsp"
- readonly property string windowsSecondLink: "SSHFS-Win"
-
- readonly property string macosFirstLink: "macFUSE"
- readonly property string macosSecondLink: "SSHFS"
-
- onLinkActivated: function(link) {
- Qt.openUrlExternally(link)
- }
- textFormat: Text.RichText
- text: {
- var str = qsTr("In order to mount remote SFTP folder as local drive, perform following steps:
")
- if (Qt.platform.os === "windows") {
- str += qsTr("
1. Install the latest version of ") + windowsFirstLink + "\n"
- str += qsTr("
2. Install the latest version of ") + windowsSecondLink + "\n"
- } else if (Qt.platform.os === "osx") {
- str += qsTr("
1. Install the latest version of ") + macosFirstLink + "\n"
- str += qsTr("
2. Install the latest version of ") + macosSecondLink + "\n"
- } else if (Qt.platform.os === "linux") {
- return ""
- } else return ""
-
- return str
- }
-
-
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.NoButton
- cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
- }
- }
-
- BasicButtonType {
- id: detailedInstructionsButton
- Layout.topMargin: 16
- Layout.bottomMargin: 16
- Layout.leftMargin: 8
- implicitHeight: 32
-
- defaultColor: AmneziaStyle.color.transparent
- hoveredColor: AmneziaStyle.color.translucentWhite
- pressedColor: AmneziaStyle.color.sheerWhite
- disabledColor: AmneziaStyle.color.mutedGray
- textColor: AmneziaStyle.color.goldenApricot
-
- text: qsTr("Detailed instructions")
-
- parentFlickable: fl
-
- clickedFunc: function() {
-// Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
- }
- }
- }
+ clickedFunc: function() {
+ // Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
}
}
}
diff --git a/client/ui/qml/Pages2/PageServiceSocksProxySettings.qml b/client/ui/qml/Pages2/PageServiceSocksProxySettings.qml
index b1daa0fb..f96872e0 100644
--- a/client/ui/qml/Pages2/PageServiceSocksProxySettings.qml
+++ b/client/ui/qml/Pages2/PageServiceSocksProxySettings.qml
@@ -25,327 +25,290 @@ PageType {
}
}
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
- BackButtonType {
- id: backButton
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: listview.implicitHeight
+ anchors.right: parent.right
+ anchors.left: parent.left
- ListView {
- id: listview
+ model: Socks5ProxyConfigModel
- width: parent.width
- height: listview.contentItem.height
+ delegate: ColumnLayout {
+ width: listView.width
- clip: true
- interactive: false
+ spacing: 0
- model: Socks5ProxyConfigModel
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- onFocusChanged: {
- if (focus) {
- listview.currentItem.focusItemId.forceActiveFocus()
+ headerText: qsTr("SOCKS5 settings")
+ }
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 16
+
+ text: qsTr("Host")
+ descriptionText: ServersModel.getProcessedServerData("hostName")
+
+ descriptionOnTop: true
+
+ rightImageSource: "qrc:/images/controls/copy.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ clickedFunction: function() {
+ GC.copyToClipBoard(descriptionText)
+ PageController.showNotificationMessage(qsTr("Copied"))
}
}
- delegate: Item {
- implicitWidth: listview.width
- implicitHeight: content.implicitHeight
+ LabelWithButtonType {
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 16
- property alias focusItemId: hostLabel.rightButton
+ text: qsTr("Port")
+ descriptionText: port
- ColumnLayout {
- id: content
+ descriptionOnTop: true
+
+ rightImageSource: "qrc:/images/controls/copy.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ clickedFunction: function() {
+ GC.copyToClipBoard(descriptionText)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 16
+
+ text: qsTr("User name")
+ descriptionText: username
+
+ descriptionOnTop: true
+
+ rightImageSource: "qrc:/images/controls/copy.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ clickedFunction: function() {
+ GC.copyToClipBoard(descriptionText)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 16
+
+ text: qsTr("Password")
+ descriptionText: password
+
+ descriptionOnTop: true
+
+ rightImageSource: "qrc:/images/controls/copy.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ buttonImageSource: hideDescription ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg"
+
+ clickedFunction: function() {
+ GC.copyToClipBoard(descriptionText)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ DrawerType2 {
+ id: changeSettingsDrawer
+ parent: root
+
+ anchors.fill: parent
+ expandedHeight: root.height * 0.9
+
+ expandedStateContent: ColumnLayout {
+ property string tempPort: port
+ property string tempUsername: username
+ property string tempPassword: password
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
+ anchors.topMargin: 32
+ anchors.leftMargin: 16
+ anchors.rightMargin: 16
spacing: 0
+ Connections {
+ target: changeSettingsDrawer
+ function onOpened() {
+ tempPort = port
+ tempUsername = username
+ tempPassword = password
+ }
+ function onClosed() {
+ port = tempPort
+ username = tempUsername
+ password = tempPassword
+ portTextField.textField.text = port
+ usernameTextField.textField.text = username
+ passwordTextField.textField.text = password
+ }
+ }
+
BaseHeaderType {
Layout.fillWidth: true
- Layout.leftMargin: 16
Layout.rightMargin: 16
+ Layout.bottomMargin: 16
headerText: qsTr("SOCKS5 settings")
}
- LabelWithButtonType {
- id: hostLabel
+ TextFieldWithHeaderType {
+ id: portTextField
+
Layout.fillWidth: true
- Layout.topMargin: 32
+ Layout.topMargin: 40
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 16
- parentFlickable: fl
+ headerText: qsTr("Port")
+ textField.text: port
+ textField.maximumLength: 5
+ textField.validator: IntValidator { bottom: 1; top: 65535 }
- text: qsTr("Host")
- descriptionText: ServersModel.getProcessedServerData("hostName")
-
- descriptionOnTop: true
-
- rightImageSource: "qrc:/images/controls/copy.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- clickedFunction: function() {
- GC.copyToClipBoard(descriptionText)
- PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
+ textField.onEditingFinished: {
+ textField.text = textField.text.replace(/^\s+|\s+$/g, '')
+ if (textField.text !== port) {
+ port = textField.text
}
}
}
- LabelWithButtonType {
- id: portLabel
+ TextFieldWithHeaderType {
+ id: usernameTextField
+
Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 16
- text: qsTr("Port")
- descriptionText: port
+ headerText: qsTr("Username")
+ textField.placeholderText: "username"
+ textField.text: username
+ textField.maximumLength: 32
- descriptionOnTop: true
-
- parentFlickable: fl
-
- rightImageSource: "qrc:/images/controls/copy.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- clickedFunction: function() {
- GC.copyToClipBoard(descriptionText)
- PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
+ textField.onEditingFinished: {
+ textField.text = textField.text.replace(/^\s+|\s+$/g, '')
+ if (textField.text !== username) {
+ username = textField.text
}
}
}
- LabelWithButtonType {
- id: usernameLabel
+ TextFieldWithHeaderType {
+ id: passwordTextField
+
+ property bool hidePassword: true
+
Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 16
- text: qsTr("User name")
- descriptionText: username
+ headerText: qsTr("Password")
+ textField.placeholderText: "password"
+ textField.text: password
+ textField.maximumLength: 32
- descriptionOnTop: true
+ textField.echoMode: hidePassword ? TextInput.Password : TextInput.Normal
+ buttonImageSource: textField.text !== "" ? (hidePassword ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg")
+ : ""
- parentFlickable: fl
-
- rightImageSource: "qrc:/images/controls/copy.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- clickedFunction: function() {
- GC.copyToClipBoard(descriptionText)
- PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
- }
+ clickedFunc: function() {
+ hidePassword = !hidePassword
}
- }
- LabelWithButtonType {
- id: passwordLabel
- Layout.fillWidth: true
-
- text: qsTr("Password")
- descriptionText: password
-
- descriptionOnTop: true
-
- parentFlickable: fl
-
- rightImageSource: "qrc:/images/controls/copy.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- buttonImageSource: hideDescription ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg"
-
- clickedFunction: function() {
- GC.copyToClipBoard(descriptionText)
- PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
- }
- }
- }
-
- DrawerType2 {
- id: changeSettingsDrawer
- parent: root
-
- anchors.fill: parent
- expandedHeight: root.height * 0.9
-
- expandedStateContent: ColumnLayout {
- property string tempPort: port
- property string tempUsername: username
- property string tempPassword: password
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 32
- anchors.leftMargin: 16
- anchors.rightMargin: 16
- spacing: 0
-
- Connections {
- target: changeSettingsDrawer
- function onOpened() {
- tempPort = port
- tempUsername = username
- tempPassword = password
- }
- function onClosed() {
- port = tempPort
- username = tempUsername
- password = tempPassword
- portTextField.textField.text = port
- usernameTextField.textField.text = username
- passwordTextField.textField.text = password
- }
- }
-
- BaseHeaderType {
- Layout.fillWidth: true
-
- headerText: qsTr("SOCKS5 settings")
- }
-
- TextFieldWithHeaderType {
- id: portTextField
-
- Layout.fillWidth: true
- Layout.topMargin: 40
- parentFlickable: fl
-
- headerText: qsTr("Port")
- textField.text: port
- textField.maximumLength: 5
- textField.validator: IntValidator { bottom: 1; top: 65535 }
-
- textField.onEditingFinished: {
- textField.text = textField.text.replace(/^\s+|\s+$/g, '')
- if (textField.text !== port) {
- port = textField.text
- }
- }
- }
-
- TextFieldWithHeaderType {
- id: usernameTextField
-
- Layout.fillWidth: true
- Layout.topMargin: 16
- parentFlickable: fl
-
- headerText: qsTr("Username")
- textField.placeholderText: "username"
- textField.text: username
- textField.maximumLength: 32
-
- textField.onEditingFinished: {
- textField.text = textField.text.replace(/^\s+|\s+$/g, '')
- if (textField.text !== username) {
- username = textField.text
- }
- }
- }
-
- TextFieldWithHeaderType {
- id: passwordTextField
-
- property bool hidePassword: true
-
- Layout.fillWidth: true
- Layout.topMargin: 16
- parentFlickable: fl
-
- headerText: qsTr("Password")
- textField.placeholderText: "password"
- textField.text: password
- textField.maximumLength: 32
-
- textField.echoMode: hidePassword ? TextInput.Password : TextInput.Normal
- buttonImageSource: textField.text !== "" ? (hidePassword ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg")
- : ""
-
- clickedFunc: function() {
- hidePassword = !hidePassword
- }
-
- textField.onFocusChanged: {
- textField.text = textField.text.replace(/^\s+|\s+$/g, '')
- if (textField.text !== password) {
- password = textField.text
- }
- }
- }
-
- BasicButtonType {
- id: saveButton
-
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 24
-
- text: qsTr("Change connection settings")
-
- clickedFunc: function() {
- forceActiveFocus()
-
- if (!portTextField.textField.acceptableInput) {
- portTextField.errorText = qsTr("The port must be in the range of 1 to 65535")
- return
- }
- if (usernameTextField.textField.text && passwordTextField.textField.text === "") {
- passwordTextField.errorText = qsTr("Password cannot be empty")
- return
- } else if (usernameTextField.textField.text === "" && passwordTextField.textField.text) {
- usernameTextField.errorText = qsTr("Username cannot be empty")
- return
- }
-
- PageController.goToPage(PageEnum.PageSetupWizardInstalling)
- InstallController.updateContainer(Socks5ProxyConfigModel.getConfig())
- tempPort = portTextField.textField.text
- tempUsername = usernameTextField.textField.text
- tempPassword = passwordTextField.textField.text
- changeSettingsDrawer.closeTriggered()
- }
+ textField.onFocusChanged: {
+ textField.text = textField.text.replace(/^\s+|\s+$/g, '')
+ if (textField.text !== password) {
+ password = textField.text
}
}
}
BasicButtonType {
- id: changeSettingsButton
+ id: saveButton
Layout.fillWidth: true
Layout.topMargin: 24
Layout.bottomMargin: 24
- Layout.leftMargin: 16
Layout.rightMargin: 16
text: qsTr("Change connection settings")
clickedFunc: function() {
- forceActiveFocus()
- changeSettingsDrawer.openTriggered()
+ if (!portTextField.textField.acceptableInput) {
+ portTextField.errorText = qsTr("The port must be in the range of 1 to 65535")
+ return
+ }
+ if (usernameTextField.textField.text && passwordTextField.textField.text === "") {
+ passwordTextField.errorText = qsTr("Password cannot be empty")
+ return
+ } else if (usernameTextField.textField.text === "" && passwordTextField.textField.text) {
+ usernameTextField.errorText = qsTr("Username cannot be empty")
+ return
+ }
+
+ PageController.goToPage(PageEnum.PageSetupWizardInstalling)
+ InstallController.updateContainer(Socks5ProxyConfigModel.getConfig())
+ tempPort = portTextField.textField.text
+ tempUsername = usernameTextField.textField.text
+ tempPassword = passwordTextField.textField.text
+ changeSettingsDrawer.closeTriggered()
}
}
}
}
+
+ BasicButtonType {
+ id: changeSettingsButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Change connection settings")
+
+ clickedFunc: function() {
+ changeSettingsDrawer.openTriggered()
+ }
+ }
}
}
}
diff --git a/client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml b/client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml
index 200beeb8..1ea1f814 100644
--- a/client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml
+++ b/client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml
@@ -25,34 +25,31 @@ PageType {
}
}
- ColumnLayout {
- id: backButtonLayout
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
-
- BackButtonType {
- id: backButton
+
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- FlickableType {
- id: fl
- anchors.top: backButtonLayout.bottom
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight
+ anchors.right: parent.right
+ anchors.left: parent.left
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- spacing: 0
+ header: ColumnLayout {
+ width: listView.width
BaseHeaderType {
Layout.fillWidth: true
@@ -61,11 +58,19 @@ PageType {
headerText: qsTr("Tor website settings")
}
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+
+ delegate: ColumnLayout { // TODO(CyAn84): add DelegateChooser after migrate to 6.9
+ width: listView.width
LabelWithButtonType {
id: websiteName
+
Layout.fillWidth: true
Layout.topMargin: 32
+ Layout.bottomMargin: 24
text: qsTr("Website address")
descriptionText: {
@@ -83,15 +88,16 @@ PageType {
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
PageController.showNotificationMessage(qsTr("Copied"))
- if (!GC.isMobile()) {
- this.rightButton.forceActiveFocus()
- }
}
}
+ }
+
+ footer: ColumnLayout {
+ width: listView.width
ParagraphTextType {
Layout.fillWidth: true
- Layout.topMargin: 40
+ Layout.topMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
diff --git a/client/ui/qml/Pages2/PageSettings.qml b/client/ui/qml/Pages2/PageSettings.qml
index bb83ec92..f331f912 100644
--- a/client/ui/qml/Pages2/PageSettings.qml
+++ b/client/ui/qml/Pages2/PageSettings.qml
@@ -1,156 +1,167 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import QtQuick.Dialogs
-
-import PageEnum 1.0
-import Style 1.0
-
-import "./"
-import "../Controls2"
-import "../Controls2/TextTypes"
-import "../Config"
-
-PageType {
- id: root
-
- FlickableType {
- id: fl
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- contentHeight: content.height
-
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- spacing: 0
-
- BaseHeaderType {
- id: header
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.rightMargin: 16
- Layout.leftMargin: 16
-
- headerText: qsTr("Settings")
- }
-
- LabelWithButtonType {
- id: account
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- text: qsTr("Servers")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
- leftImageSource: "qrc:/images/controls/server.svg"
-
- clickedFunction: function() {
- PageController.goToPage(PageEnum.PageSettingsServersList)
- }
- }
-
- DividerType {}
-
- LabelWithButtonType {
- id: connection
- Layout.fillWidth: true
-
- text: qsTr("Connection")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
- leftImageSource: "qrc:/images/controls/radio.svg"
-
- clickedFunction: function() {
- PageController.goToPage(PageEnum.PageSettingsConnection)
- }
- }
-
- DividerType {}
-
- LabelWithButtonType {
- id: application
- Layout.fillWidth: true
-
- text: qsTr("Application")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
- leftImageSource: "qrc:/images/controls/app.svg"
-
- clickedFunction: function() {
- PageController.goToPage(PageEnum.PageSettingsApplication)
- }
- }
-
- DividerType {}
-
- LabelWithButtonType {
- id: backup
- Layout.fillWidth: true
-
- text: qsTr("Backup")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
- leftImageSource: "qrc:/images/controls/save.svg"
-
- clickedFunction: function() {
- PageController.goToPage(PageEnum.PageSettingsBackup)
- }
- }
-
- DividerType {}
-
- LabelWithButtonType {
- id: about
- Layout.fillWidth: true
-
- text: qsTr("About AmneziaVPN")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
- leftImageSource: "qrc:/images/controls/amnezia.svg"
-
- clickedFunction: function() {
- PageController.goToPage(PageEnum.PageSettingsAbout)
- }
- }
-
- DividerType {}
-
- LabelWithButtonType {
- id: devConsole
- visible: SettingsController.isDevModeEnabled
- Layout.fillWidth: true
-
- text: qsTr("Dev console")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
- leftImageSource: "qrc:/images/controls/bug.svg"
-
- clickedFunction: function() {
- PageController.goToPage(PageEnum.PageDevMenu)
- }
- }
-
- DividerType {
- visible: SettingsController.isDevModeEnabled
- }
-
- LabelWithButtonType {
- id: close
- visible: GC.isDesktop()
- Layout.fillWidth: true
- Layout.preferredHeight: about.height
-
- text: qsTr("Close application")
- leftImageSource: "qrc:/images/controls/x-circle.svg"
- isLeftImageHoverEnabled: false
-
- clickedFunction: function() {
- PageController.closeApplication()
- }
- }
-
- DividerType {
- visible: GC.isDesktop()
- }
- }
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Dialogs
+
+import PageEnum 1.0
+import Style 1.0
+
+import "./"
+import "../Controls2"
+import "../Controls2/TextTypes"
+import "../Config"
+
+PageType {
+ id: root
+
+ ListViewType {
+ id: listView
+
+ anchors.fill: parent
+
+ header: ColumnLayout {
+ width: listView.width
+
+ BaseHeaderType {
+ id: header
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 16
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ headerText: qsTr("Settings")
+ }
+ }
+
+ model: settingsEntries
+
+ delegate: ColumnLayout {
+ width: listView.width
+
+ spacing: 0
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ visible: isVisible
+
+ text: title
+ rightImageSource: "qrc:/images/controls/chevron-right.svg"
+ leftImageSource: leftImagePath
+
+ clickedFunction: clickedHandler
+ }
+
+ DividerType {
+ visible: isVisible
+ }
+ }
+
+ footer: ColumnLayout {
+ width: listView.width
+
+ LabelWithButtonType {
+ id: close
+
+ visible: GC.isDesktop()
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Close application")
+ leftImageSource: "qrc:/images/controls/x-circle.svg"
+ isLeftImageHoverEnabled: false
+
+ clickedFunction: function() {
+ PageController.closeApplication()
+ }
+ }
+
+ DividerType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ visible: GC.isDesktop()
+ }
+ }
+ }
+
+ property list settingsEntries: [
+ servers,
+ connection,
+ application,
+ backup,
+ about,
+ devConsole
+ ]
+
+ QtObject {
+ id: servers
+
+ property string title: qsTr("Servers")
+ readonly property string leftImagePath: "qrc:/images/controls/server.svg"
+ property bool isVisible: true
+ readonly property var clickedHandler: function() {
+ PageController.goToPage(PageEnum.PageSettingsServersList)
+ }
+ }
+
+ QtObject {
+ id: connection
+
+ property string title: qsTr("Connection")
+ readonly property string leftImagePath: "qrc:/images/controls/radio.svg"
+ property bool isVisible: true
+ readonly property var clickedHandler: function() {
+ PageController.goToPage(PageEnum.PageSettingsConnection)
+ }
+ }
+
+ QtObject {
+ id: application
+
+ property string title: qsTr("Application")
+ readonly property string leftImagePath: "qrc:/images/controls/app.svg"
+ property bool isVisible: true
+ readonly property var clickedHandler: function() {
+ PageController.goToPage(PageEnum.PageSettingsApplication)
+ }
+ }
+
+ QtObject {
+ id: backup
+
+ property string title: qsTr("Backup")
+ readonly property string leftImagePath: "qrc:/images/controls/save.svg"
+ property bool isVisible: true
+ readonly property var clickedHandler: function() {
+ PageController.goToPage(PageEnum.PageSettingsBackup)
+ }
+ }
+
+ QtObject {
+ id: about
+
+ property string title: qsTr("About AmneziaVPN")
+ readonly property string leftImagePath: "qrc:/images/controls/amnezia.svg"
+ property bool isVisible: true
+ readonly property var clickedHandler: function() {
+ PageController.goToPage(PageEnum.PageSettingsAbout)
+ }
+ }
+
+ QtObject {
+ id: devConsole
+
+ property string title: qsTr("Dev console")
+ readonly property string leftImagePath: "qrc:/images/controls/bug.svg"
+ property bool isVisible: SettingsController.isDevModeEnabled
+ readonly property var clickedHandler: function() {
+ PageController.goToPage(PageEnum.PageDevMenu)
+ }
+ }
+}
diff --git a/client/ui/qml/Pages2/PageSettingsAbout.qml b/client/ui/qml/Pages2/PageSettingsAbout.qml
index 6342ce66..a3c2b884 100644
--- a/client/ui/qml/Pages2/PageSettingsAbout.qml
+++ b/client/ui/qml/Pages2/PageSettingsAbout.qml
@@ -29,58 +29,7 @@ PageType {
}
}
- QtObject {
- id: telegramGroup
-
- readonly property string title: qsTr("Telegram group")
- readonly property string description: qsTr("To discuss features")
- readonly property string imageSource: "qrc:/images/controls/telegram.svg"
- readonly property var handler: function() {
- Qt.openUrlExternally(qsTr("https://t.me/amnezia_vpn_en"))
- }
- }
-
- QtObject {
- id: mail
-
- readonly property string title: qsTr("support@amnezia.org")
- readonly property string description: qsTr("For reviews and bug reports")
- readonly property string imageSource: "qrc:/images/controls/mail.svg"
- readonly property var handler: function() {
- Qt.openUrlExternally(qsTr("mailto:support@amnezia.org"))
- }
- }
-
- QtObject {
- id: github
-
- readonly property string title: qsTr("GitHub")
- readonly property string description: qsTr("Discover the source code")
- readonly property string imageSource: "qrc:/images/controls/github.svg"
- readonly property var handler: function() {
- Qt.openUrlExternally(qsTr("https://github.com/amnezia-vpn/amnezia-client"))
- }
- }
-
- QtObject {
- id: website
-
- readonly property string title: qsTr("Website")
- readonly property string description: qsTr("Visit official website")
- readonly property string imageSource: "qrc:/images/controls/amnezia.svg"
- readonly property var handler: function() {
- Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
- }
- }
-
- property list contacts: [
- telegramGroup,
- mail,
- github,
- website
- ]
-
- ListView {
+ ListViewType {
id: listView
anchors.top: backButton.bottom
@@ -88,38 +37,6 @@ PageType {
anchors.right: parent.right
anchors.left: parent.left
- property bool isFocusable: true
-
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
- ScrollBar.vertical: ScrollBarType {}
-
- model: contacts
-
- clip: true
-
header: ColumnLayout {
width: listView.width
@@ -170,11 +87,12 @@ PageType {
}
}
+ model: contacts
+
delegate: ColumnLayout {
width: listView.width
LabelWithButtonType {
- id: telegramButton
Layout.fillWidth: true
Layout.topMargin: 6
@@ -257,4 +175,55 @@ PageType {
}
}
}
+
+ property list contacts: [
+ telegramGroup,
+ mail,
+ github,
+ website
+ ]
+
+ QtObject {
+ id: telegramGroup
+
+ readonly property string title: qsTr("Telegram group")
+ readonly property string description: qsTr("To discuss features")
+ readonly property string imageSource: "qrc:/images/controls/telegram.svg"
+ readonly property var handler: function() {
+ Qt.openUrlExternally(qsTr("https://t.me/amnezia_vpn_en"))
+ }
+ }
+
+ QtObject {
+ id: mail
+
+ readonly property string title: qsTr("support@amnezia.org")
+ readonly property string description: qsTr("For reviews and bug reports")
+ readonly property string imageSource: "qrc:/images/controls/mail.svg"
+ readonly property var handler: function() {
+ Qt.openUrlExternally(qsTr("mailto:support@amnezia.org"))
+ }
+ }
+
+ QtObject {
+ id: github
+
+ readonly property string title: qsTr("GitHub")
+ readonly property string description: qsTr("Discover the source code")
+ readonly property string imageSource: "qrc:/images/controls/github.svg"
+ readonly property var handler: function() {
+ Qt.openUrlExternally(qsTr("https://github.com/amnezia-vpn/amnezia-client"))
+ }
+ }
+
+ QtObject {
+ id: website
+
+ readonly property string title: qsTr("Website")
+ readonly property string description: qsTr("Visit official website")
+ readonly property string imageSource: "qrc:/images/controls/amnezia.svg"
+ readonly property var handler: function() {
+ Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
+ }
+ }
}
diff --git a/client/ui/qml/Pages2/PageSettingsApiNativeConfigs.qml b/client/ui/qml/Pages2/PageSettingsApiNativeConfigs.qml
index 8fa85a33..39e2e626 100644
--- a/client/ui/qml/Pages2/PageSettingsApiNativeConfigs.qml
+++ b/client/ui/qml/Pages2/PageSettingsApiNativeConfigs.qml
@@ -1,221 +1,243 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import QtQuick.Dialogs
-
-import QtCore
-
-import SortFilterProxyModel 0.2
-
-import PageEnum 1.0
-import Style 1.0
-
-import "./"
-import "../Controls2"
-import "../Controls2/TextTypes"
-import "../Config"
-import "../Components"
-
-PageType {
- id: root
-
- property string configExtension: ".conf"
- property string configCaption: qsTr("Save AmneziaVPN config")
-
- ListViewType {
- id: listView
-
- anchors.fill: parent
- anchors.topMargin: 20
- anchors.bottomMargin: 24
-
- model: ApiCountryModel
-
- header: ColumnLayout {
- width: listView.width
-
- BackButtonType {
- id: backButton
- }
-
- BaseHeaderType {
- id: header
-
- Layout.fillWidth: true
- Layout.rightMargin: 16
- Layout.leftMargin: 16
-
- headerText: qsTr("Configuration Files")
- descriptionText: qsTr("For router setup or the AmneziaWG app")
- }
- }
-
- delegate: ColumnLayout {
- width: listView.width
-
- LabelWithButtonType {
- Layout.fillWidth: true
- Layout.topMargin: 6
-
- text: countryName
- descriptionText: isWorkerExpired ? qsTr("Download the update") : ""
- hideDescription: false
- descriptionColor: AmneziaStyle.color.mutedGray
-
- leftImageSource: "qrc:/countriesFlags/images/flagKit/" + countryImageCode + ".svg"
- rightImageSource: isIssued ? "qrc:/images/controls/more-vertical.svg" : "qrc:/images/controls/download.svg"
-
- clickedFunction: function() {
- if (isIssued) {
- moreOptionsDrawer.countryName = countryName
- moreOptionsDrawer.countryCode = countryCode
- moreOptionsDrawer.openTriggered()
- } else {
- issueConfig(countryCode)
- }
- }
- }
-
- DividerType {}
- }
- }
-
- DrawerType2 {
- id: moreOptionsDrawer
-
- property string countryName
- property string countryCode
-
- anchors.fill: parent
- expandedHeight: parent.height * 0.4375
-
- expandedStateContent: Item {
- implicitHeight: moreOptionsDrawer.expandedHeight
-
- BackButtonType {
- id: moreOptionsDrawerBackButton
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 16
-
- backButtonFunction: function() {
- moreOptionsDrawer.closeTriggered()
- }
- }
-
- FlickableType {
- anchors.top: moreOptionsDrawerBackButton.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
-
- contentHeight: moreOptionsDrawerContent.height
-
- ColumnLayout {
- id: moreOptionsDrawerContent
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- Header2Type {
- Layout.fillWidth: true
- Layout.margins: 16
-
- headerText: moreOptionsDrawer.countryName + qsTr(" configuration file")
- }
-
- LabelWithButtonType {
- Layout.fillWidth: true
-
- text: qsTr("Generate a new configuration file")
- descriptionText: qsTr("The previously created one will stop working")
-
- clickedFunction: function() {
- showQuestion(true, moreOptionsDrawer.countryCode, moreOptionsDrawer.countryName)
- }
- }
-
- DividerType {}
-
- LabelWithButtonType {
- Layout.fillWidth: true
- text: qsTr("Revoke the current configuration file")
-
- clickedFunction: function() {
- showQuestion(false, moreOptionsDrawer.countryCode, moreOptionsDrawer.countryName)
- }
- }
-
- DividerType {}
- }
- }
- }
- }
-
- function issueConfig(countryCode) {
- var fileName = ""
- if (GC.isMobile()) {
- fileName = countryCode + configExtension
- } else {
- fileName = SystemController.getFileName(configCaption,
- qsTr("Config files (*" + configExtension + ")"),
- StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/" + countryCode,
- true,
- configExtension)
- }
- if (fileName !== "") {
- PageController.showBusyIndicator(true)
- let result = ApiConfigsController.exportNativeConfig(countryCode, fileName)
- if (result) {
- ApiSettingsController.getAccountInfo(true)
- }
-
- PageController.showBusyIndicator(false)
- if (result) {
- PageController.showNotificationMessage(qsTr("Config file saved"))
- }
- }
- }
-
- function revokeConfig(countryCode) {
- PageController.showBusyIndicator(true)
- let result = ApiConfigsController.revokeNativeConfig(countryCode)
- if (result) {
- ApiSettingsController.getAccountInfo(true)
- }
- PageController.showBusyIndicator(false)
-
- if (result) {
- PageController.showNotificationMessage(qsTr("The config has been revoked"))
- }
- }
-
- function showQuestion(isConfigIssue, countryCode, countryName) {
- var headerText
- if (isConfigIssue) {
- headerText = qsTr("Generate a new %1 configuration file?").arg(countryName)
- } else {
- headerText = qsTr("Revoke the current %1 configuration file?").arg(countryName)
- }
-
- var descriptionText = qsTr("Your previous configuration file will no longer work, and it will not be possible to connect using it")
- var yesButtonText = isConfigIssue ? qsTr("Download") : qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (isConfigIssue) {
- issueConfig(countryCode)
- } else {
- revokeConfig(countryCode)
- }
- moreOptionsDrawer.closeTriggered()
- }
- var noButtonFunction = function() {
- }
-
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Dialogs
+
+import QtCore
+
+import SortFilterProxyModel 0.2
+
+import PageEnum 1.0
+import Style 1.0
+
+import "./"
+import "../Controls2"
+import "../Controls2/TextTypes"
+import "../Config"
+import "../Components"
+
+PageType {
+ id: root
+
+ property string configExtension: ".conf"
+ property string configCaption: qsTr("Save AmneziaVPN config")
+
+ BackButtonType {
+ id: backButton
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
+
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
+ }
+
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+
+ model: ApiCountryModel
+
+ header: ColumnLayout {
+ width: listView.width
+
+ BaseHeaderType {
+ id: header
+
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ headerText: qsTr("Configuration Files")
+ descriptionText: qsTr("For router setup or the AmneziaWG app")
+ }
+ }
+
+ delegate: ColumnLayout {
+ width: listView.width
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+ Layout.topMargin: 6
+
+ text: countryName
+ descriptionText: isWorkerExpired ? qsTr("The configuration needs to be reissued") : ""
+ hideDescription: isWorkerExpired : true : false
+ descriptionColor: AmneziaStyle.color.vibrantRed
+
+ leftImageSource: "qrc:/countriesFlags/images/flagKit/" + countryImageCode + ".svg"
+ rightImageSource: isIssued ? "qrc:/images/controls/more-vertical.svg" : "qrc:/images/controls/download.svg"
+
+ clickedFunction: function() {
+ if (isIssued) {
+ moreOptionsDrawer.countryName = countryName
+ moreOptionsDrawer.countryCode = countryCode
+ moreOptionsDrawer.openTriggered()
+ } else {
+ issueConfig(countryCode)
+ }
+ }
+ }
+
+ DividerType {}
+ }
+ }
+
+ DrawerType2 {
+ id: moreOptionsDrawer
+
+ property string countryName
+ property string countryCode
+
+ anchors.fill: parent
+ expandedHeight: parent.height * 0.4375
+
+ expandedStateContent: Item {
+ implicitHeight: moreOptionsDrawer.expandedHeight
+
+ BackButtonType {
+ id: moreOptionsDrawerBackButton
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 16
+
+ backButtonFunction: function() {
+ moreOptionsDrawer.closeTriggered()
+ }
+ }
+
+ ListViewType {
+ id: drawerListView
+
+ anchors.top: moreOptionsDrawerBackButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ header: ColumnLayout {
+ width: drawerListView.width
+
+ Header2Type {
+ Layout.fillWidth: true
+ Layout.margins: 16
+
+ headerText: moreOptionsDrawer.countryName + qsTr(" configuration file")
+ }
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+
+ delegate: ColumnLayout {
+ width: drawerListView.width
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Generate a new configuration file")
+ descriptionText: qsTr("The previously created one will stop working")
+
+ clickedFunction: function() {
+ showQuestion(true, moreOptionsDrawer.countryCode, moreOptionsDrawer.countryName)
+ }
+ }
+
+ DividerType {}
+ }
+
+ footer: ColumnLayout {
+ width: drawerListView.width
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Revoke the current configuration file")
+
+ clickedFunction: function() {
+ showQuestion(false, moreOptionsDrawer.countryCode, moreOptionsDrawer.countryName)
+ }
+ }
+
+ DividerType {}
+ }
+ }
+ }
+ }
+
+ function issueConfig(countryCode) {
+ var fileName = ""
+ if (GC.isMobile()) {
+ fileName = countryCode + configExtension
+ } else {
+ fileName = SystemController.getFileName(configCaption,
+ qsTr("Config files (*" + configExtension + ")"),
+ StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/" + countryCode,
+ true,
+ configExtension)
+ }
+ if (fileName !== "") {
+ PageController.showBusyIndicator(true)
+ let result = ApiConfigsController.exportNativeConfig(countryCode, fileName)
+ if (result) {
+ ApiSettingsController.getAccountInfo(true)
+ }
+
+ PageController.showBusyIndicator(false)
+ if (result) {
+ PageController.showNotificationMessage(qsTr("Config file saved"))
+ }
+ }
+ }
+
+ function revokeConfig(countryCode) {
+ PageController.showBusyIndicator(true)
+ let result = ApiConfigsController.revokeNativeConfig(countryCode)
+ if (result) {
+ ApiSettingsController.getAccountInfo(true)
+ }
+ PageController.showBusyIndicator(false)
+
+ if (result) {
+ PageController.showNotificationMessage(qsTr("The config has been revoked"))
+ }
+ }
+
+ function showQuestion(isConfigIssue, countryCode, countryName) {
+ var headerText
+ if (isConfigIssue) {
+ headerText = qsTr("Generate a new %1 configuration file?").arg(countryName)
+ } else {
+ headerText = qsTr("Revoke the current %1 configuration file?").arg(countryName)
+ }
+
+ var descriptionText = qsTr("Your previous configuration file will no longer work, and it will not be possible to connect using it")
+ var yesButtonText = isConfigIssue ? qsTr("Download") : qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ if (isConfigIssue) {
+ issueConfig(countryCode)
+ } else {
+ revokeConfig(countryCode)
+ }
+ moreOptionsDrawer.closeTriggered()
+ }
+ var noButtonFunction = function() {}
+
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+}
diff --git a/client/ui/qml/Pages2/PageSettingsAppSplitTunneling.qml b/client/ui/qml/Pages2/PageSettingsAppSplitTunneling.qml
index e31c92db..60b59f45 100644
--- a/client/ui/qml/Pages2/PageSettingsAppSplitTunneling.qml
+++ b/client/ui/qml/Pages2/PageSettingsAppSplitTunneling.qml
@@ -50,6 +50,7 @@ PageType {
readonly property string name: qsTr("Only the apps from the list should have access via VPN")
readonly property int type: routeMode.onlyForwardApps
}
+
QtObject {
id: allExceptApps
@@ -111,7 +112,7 @@ PageType {
headerText: qsTr("Mode")
- enabled: Qt.platform.os === "android" && root.pageEnabled
+ enabled: (Qt.platform.os === "android") && root.pageEnabled
listView: ListViewWithRadioButtonType {
rootWidth: root.width
@@ -146,77 +147,56 @@ PageType {
}
}
- FlickableType {
+ ListViewType {
+ id: listView
+
anchors.top: header.bottom
- anchors.topMargin: 16
- contentHeight: col.implicitHeight + addAppButton.implicitHeight + addAppButton.anchors.bottomMargin + addAppButton.anchors.topMargin
+ anchors.bottom: addAppButton.top
+ anchors.left: parent.left
+ anchors.right: parent.right
- enabled: root.pageEnabled
+ model: SortFilterProxyModel {
+ id: proxyAppSplitTunnelingModel
+ sourceModel: AppSplitTunnelingModel
+ filters: RegExpFilter {
+ roleName: "appPath"
+ pattern: ".*" + searchField.textField.text + ".*"
+ caseSensitivity: Qt.CaseInsensitive
+ }
+ sorters: [
+ RoleSorter { roleName: "appPath"; sortOrder: Qt.AscendingOrder }
+ ]
+ }
- Column {
- id: col
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ delegate: ColumnLayout {
+ width: listView.width
- ListView {
- id: apps
- width: parent.width
- height: apps.contentItem.height
+ LabelWithButtonType {
+ Layout.fillWidth: true
- model: SortFilterProxyModel {
- id: proxyAppSplitTunnelingModel
- sourceModel: AppSplitTunnelingModel
- filters: RegExpFilter {
- roleName: "appPath"
- pattern: ".*" + searchField.textField.text + ".*"
- caseSensitivity: Qt.CaseInsensitive
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: appPath
+ rightImageSource: "qrc:/images/controls/trash.svg"
+ rightImageColor: AmneziaStyle.color.paleGray
+
+ clickedFunction: function() {
+ var headerText = qsTr("Remove ") + appPath + "?"
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ AppSplitTunnelingController.removeApp(proxyAppSplitTunnelingModel.mapToSource(index))
}
- sorters: [
- RoleSorter { roleName: "appPath"; sortOrder: Qt.AscendingOrder }
- ]
- }
-
- clip: true
- interactive: false
-
- delegate: Item {
- implicitWidth: apps.width
- implicitHeight: delegateContent.implicitHeight
-
- ColumnLayout {
- id: delegateContent
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- LabelWithButtonType {
- Layout.fillWidth: true
-
- text: appPath
- rightImageSource: "qrc:/images/controls/trash.svg"
- rightImageColor: AmneziaStyle.color.paleGray
-
- clickedFunction: function() {
- var headerText = qsTr("Remove ") + appPath + "?"
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- AppSplitTunnelingController.removeApp(proxyAppSplitTunnelingModel.mapToSource(index))
- }
- var noButtonFunction = function() {
- }
-
- showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
- }
-
- DividerType {}
+ var noButtonFunction = function() {
}
+
+ showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
}
+
+ DividerType {}
}
}
diff --git a/client/ui/qml/Pages2/PageSettingsApplication.qml b/client/ui/qml/Pages2/PageSettingsApplication.qml
index 5f4ada82..981bbecb 100644
--- a/client/ui/qml/Pages2/PageSettingsApplication.qml
+++ b/client/ui/qml/Pages2/PageSettingsApplication.qml
@@ -21,22 +21,24 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
+
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
}
- FlickableType {
- id: fl
+ ListViewType {
+ id: listView
+
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.height
+ anchors.left: parent.left
+ anchors.right: parent.right
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- spacing: 0
+ header: ColumnLayout {
+ width: listView.width
BaseHeaderType {
Layout.fillWidth: true
@@ -45,9 +47,17 @@ PageType {
headerText: qsTr("Application")
}
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+
+ delegate: ColumnLayout { // TODO(CyAn84): add DelegateChooser when have migrated to 6.9
+
+ width: listView.width
SwitcherType {
- id: switcher
+ id: switcherAllowScreenshots
+
visible: GC.isMobile()
Layout.fillWidth: true
@@ -61,10 +71,6 @@ PageType {
SettingsController.toggleScreenshotsEnabled(checked)
}
}
-
- // KeyNavigation.tab: Qt.platform.os === "android" && !SettingsController.isNotificationPermissionGranted ?
- // labelWithButtonNotification.rightButton : labelWithButtonLanguage.rightButton
- parentFlickable: fl
}
DividerType {
@@ -73,15 +79,15 @@ PageType {
LabelWithButtonType {
id: labelWithButtonNotification
+
visible: Qt.platform.os === "android" && !SettingsController.isNotificationPermissionGranted
+
Layout.fillWidth: true
text: qsTr("Enable notifications")
descriptionText: qsTr("Enable notifications to show the VPN state in the status bar")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
- parentFlickable: fl
-
clickedFunction: function() {
SettingsController.requestNotificationPermission()
}
@@ -93,6 +99,7 @@ PageType {
SwitcherType {
id: switcherAutoStart
+
visible: !GC.isMobile()
Layout.fillWidth: true
@@ -101,8 +108,6 @@ PageType {
text: qsTr("Auto start")
descriptionText: qsTr("Launch the application every time the device is starts")
- parentFlickable: fl
-
checked: SettingsController.isAutoStartEnabled()
onCheckedChanged: {
if (checked !== SettingsController.isAutoStartEnabled()) {
@@ -117,6 +122,7 @@ PageType {
SwitcherType {
id: switcherAutoConnect
+
visible: !GC.isMobile()
Layout.fillWidth: true
@@ -125,8 +131,6 @@ PageType {
text: qsTr("Auto connect")
descriptionText: qsTr("Connect to VPN on app start")
- parentFlickable: fl
-
checked: SettingsController.isAutoConnectEnabled()
onCheckedChanged: {
if (checked !== SettingsController.isAutoConnectEnabled()) {
@@ -141,6 +145,7 @@ PageType {
SwitcherType {
id: switcherStartMinimized
+
visible: !GC.isMobile()
Layout.fillWidth: true
@@ -152,8 +157,6 @@ PageType {
enabled: switcherAutoStart.checked
opacity: enabled ? 1.0 : 0.5
- parentFlickable: fl
-
checked: SettingsController.isStartMinimizedEnabled()
onCheckedChanged: {
if (checked !== SettingsController.isStartMinimizedEnabled()) {
@@ -165,17 +168,21 @@ PageType {
DividerType {
visible: !GC.isMobile()
}
+ }
+
+ footer: ColumnLayout {
+
+ width: listView.width
LabelWithButtonType {
id: labelWithButtonLanguage
+
Layout.fillWidth: true
text: qsTr("Language")
descriptionText: LanguageModel.currentLanguageName
rightImageSource: "qrc:/images/controls/chevron-right.svg"
- parentFlickable: fl
-
clickedFunction: function() {
selectLanguageDrawer.openTriggered()
}
@@ -185,14 +192,13 @@ PageType {
LabelWithButtonType {
id: labelWithButtonLogging
+
Layout.fillWidth: true
text: qsTr("Logging")
descriptionText: SettingsController.isLoggingEnabled ? qsTr("Enabled") : qsTr("Disabled")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
- parentFlickable: fl
-
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsLogging)
}
@@ -202,14 +208,13 @@ PageType {
LabelWithButtonType {
id: labelWithButtonReset
+
Layout.fillWidth: true
text: qsTr("Reset settings and remove all data from the application")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
textColor: AmneziaStyle.color.vibrantRed
- parentFlickable: fl
-
clickedFunction: function() {
var headerText = qsTr("Reset settings and remove all data from the application?")
var descriptionText = qsTr("All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.")
diff --git a/client/ui/qml/Pages2/PageSettingsBackup.qml b/client/ui/qml/Pages2/PageSettingsBackup.qml
index 83e0f567..a8ea9da7 100644
--- a/client/ui/qml/Pages2/PageSettingsBackup.qml
+++ b/client/ui/qml/Pages2/PageSettingsBackup.qml
@@ -41,51 +41,68 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
+
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
}
- FlickableType {
- id: fl
+ ListViewType {
+ id: listView
+
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.height
+ anchors.left: parent.left
+ anchors.right: parent.right
- ColumnLayout {
- id: content
+ header: ColumnLayout {
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.leftMargin: 16
- anchors.rightMargin: 16
+ width: listView.width
spacing: 16
BaseHeaderType {
Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
headerText: qsTr("Back up your configuration")
descriptionText: qsTr("You can save your settings to a backup file to restore them the next time you install the application.")
}
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+
+ delegate: ColumnLayout { // TODO(CyAn84): add DelegateChooser when have migrated to 6.9
+
+ width: listView.width
+
+ spacing: 16
WarningType {
- Layout.topMargin: 16
Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
textString: qsTr("The backup will contain your passwords and private keys for all servers added " +
- "to AmneziaVPN. Keep this information in a secure place.")
+ "to AmneziaVPN. Keep this information in a secure place.")
iconPath: "qrc:/images/controls/alert-circle.svg"
}
BasicButtonType {
id: makeBackupButton
+
Layout.fillWidth: true
Layout.topMargin: 14
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
text: qsTr("Make a backup")
- parentFlickable: fl
-
clickedFunc: function() {
var fileName = ""
if (GC.isMobile()) {
@@ -108,8 +125,11 @@ PageType {
BasicButtonType {
id: restoreBackupButton
+
Layout.fillWidth: true
Layout.topMargin: -8
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.translucentWhite
@@ -120,8 +140,6 @@ PageType {
text: qsTr("Restore from backup")
- parentFlickable: fl
-
clickedFunc: function() {
var filePath = SystemController.getFileName(qsTr("Open backup file"),
qsTr("Backup files (*.backup)"))
diff --git a/client/ui/qml/Pages2/PageSettingsConnection.qml b/client/ui/qml/Pages2/PageSettingsConnection.qml
index 84b98230..60323629 100644
--- a/client/ui/qml/Pages2/PageSettingsConnection.qml
+++ b/client/ui/qml/Pages2/PageSettingsConnection.qml
@@ -21,20 +21,25 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
+
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
}
- FlickableType {
- id: fl
+ ListViewType {
+ id: listView
+
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.height
+ anchors.left: parent.left
+ anchors.right: parent.right
- ColumnLayout {
- id: content
+ header: ColumnLayout {
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ width: listView.width
BaseHeaderType {
Layout.fillWidth: true
@@ -43,9 +48,17 @@ PageType {
headerText: qsTr("Connection")
}
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+
+ delegate: ColumnLayout { // TODO(CyAn84): add DelegateChooser when have migrated to 6.9
+
+ width: listView.width
SwitcherType {
id: amneziaDnsSwitch
+
Layout.fillWidth: true
Layout.margins: 16
@@ -64,14 +77,13 @@ PageType {
LabelWithButtonType {
id: dnsServersButton
+
Layout.fillWidth: true
text: qsTr("DNS servers")
descriptionText: qsTr("When AmneziaDNS is not used or installed")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
- parentFlickable: fl
-
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsDns)
}
@@ -81,14 +93,13 @@ PageType {
LabelWithButtonType {
id: splitTunnelingButton
+
Layout.fillWidth: true
text: qsTr("Site-based split tunneling")
descriptionText: qsTr("Allows you to select which sites you want to access through the VPN")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
- parentFlickable: fl
-
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
}
@@ -96,8 +107,15 @@ PageType {
DividerType {}
+ }
+
+ footer: ColumnLayout { // TODO(CyAn84): move to delegate,add DelegateChooser when have migrated to 6.9
+
+ width: listView.width
+
LabelWithButtonType {
id: splitTunnelingButton2
+
visible: root.isAppSplitTinnelingEnabled
Layout.fillWidth: true
@@ -106,8 +124,6 @@ PageType {
descriptionText: qsTr("Allows you to use the VPN only for certain Apps")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
- parentFlickable: fl
-
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
}
@@ -127,8 +143,6 @@ PageType {
descriptionText: qsTr("Blocks network connections without VPN")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
- parentFlickable: fl
-
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsKillSwitch)
}
diff --git a/client/ui/qml/Pages2/PageSettingsDns.qml b/client/ui/qml/Pages2/PageSettingsDns.qml
index d5e2c52b..a510f928 100644
--- a/client/ui/qml/Pages2/PageSettingsDns.qml
+++ b/client/ui/qml/Pages2/PageSettingsDns.qml
@@ -1,140 +1,167 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-
-import PageEnum 1.0
-import Style 1.0
-
-import "./"
-import "../Controls2"
-import "../Config"
-import "../Controls2/TextTypes"
-import "../Components"
-
-PageType {
- id: root
-
- BackButtonType {
- id: backButton
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 20
- }
-
- FlickableType {
- id: fl
- anchors.top: backButton.bottom
- anchors.bottom: parent.bottom
- contentHeight: content.height
-
- property var isServerFromApi: ServersModel.isServerFromApi(ServersModel.defaultIndex)
-
- enabled: !isServerFromApi
-
- Component.onCompleted: {
- if (isServerFromApi) {
- PageController.showNotificationMessage(qsTr("Default server does not support custom DNS"))
- }
- }
-
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.leftMargin: 16
- anchors.rightMargin: 16
-
- spacing: 16
-
- BaseHeaderType {
- Layout.fillWidth: true
-
- headerText: qsTr("DNS servers")
- }
-
- ParagraphTextType {
- Layout.fillWidth: true
- text: qsTr("If AmneziaDNS is not used or installed")
- }
-
- TextFieldWithHeaderType {
- id: primaryDns
-
- Layout.fillWidth: true
- headerText: qsTr("Primary DNS")
-
- textField.text: SettingsController.primaryDns
- textField.validator: RegularExpressionValidator {
- regularExpression: InstallController.ipAddressRegExp()
- }
- }
-
- TextFieldWithHeaderType {
- id: secondaryDns
-
- Layout.fillWidth: true
- headerText: qsTr("Secondary DNS")
-
- textField.text: SettingsController.secondaryDns
- textField.validator: RegularExpressionValidator {
- regularExpression: InstallController.ipAddressRegExp()
- }
- }
-
- BasicButtonType {
- id: restoreDefaultButton
- Layout.fillWidth: true
-
- defaultColor: AmneziaStyle.color.transparent
- hoveredColor: AmneziaStyle.color.translucentWhite
- pressedColor: AmneziaStyle.color.sheerWhite
- disabledColor: AmneziaStyle.color.mutedGray
- textColor: AmneziaStyle.color.paleGray
- borderWidth: 1
-
- text: qsTr("Restore default")
-
- clickedFunc: function() {
- var headerText = qsTr("Restore default DNS settings?")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- SettingsController.primaryDns = "1.1.1.1"
- primaryDns.textField.text = SettingsController.primaryDns
- SettingsController.secondaryDns = "1.0.0.1"
- secondaryDns.textField.text = SettingsController.secondaryDns
- PageController.showNotificationMessage(qsTr("Settings have been reset"))
- }
- var noButtonFunction = function() {
- }
-
- showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
- }
-
- BasicButtonType {
- id: saveButton
-
- Layout.fillWidth: true
-
- text: qsTr("Save")
-
- clickedFunc: function() {
- if (primaryDns.textField.text !== SettingsController.primaryDns) {
- SettingsController.primaryDns = primaryDns.textField.text
- }
- if (secondaryDns.textField.text !== SettingsController.secondaryDns) {
- SettingsController.secondaryDns = secondaryDns.textField.text
- }
- PageController.showNotificationMessage(qsTr("Settings saved"))
- }
- }
- }
- }
-
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import PageEnum 1.0
+import Style 1.0
+
+import "./"
+import "../Controls2"
+import "../Config"
+import "../Controls2/TextTypes"
+import "../Components"
+
+PageType {
+ id: root
+
+ BackButtonType {
+ id: backButton
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
+
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
+ }
+
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+
+ property var isServerFromApi: ServersModel.isServerFromApi(ServersModel.defaultIndex)
+
+ enabled: !isServerFromApi
+
+ Component.onCompleted: {
+ if (isServerFromApi) {
+ PageController.showNotificationMessage(qsTr("Default server does not support custom DNS"))
+ }
+ }
+
+ header: ColumnLayout {
+ width: listView.width
+ spacing: 16
+
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("DNS servers")
+ }
+
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("If AmneziaDNS is not used or installed")
+ }
+
+ TextFieldWithHeaderType {
+ id: primaryDns
+
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("Primary DNS")
+
+ textField.text: SettingsController.primaryDns
+ textField.validator: RegularExpressionValidator {
+ regularExpression: InstallController.ipAddressRegExp()
+ }
+ }
+
+ TextFieldWithHeaderType {
+ id: secondaryDns
+
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("Secondary DNS")
+
+ textField.text: SettingsController.secondaryDns
+ textField.validator: RegularExpressionValidator {
+ regularExpression: InstallController.ipAddressRegExp()
+ }
+ }
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+ spacing: 16
+
+ delegate: ColumnLayout {
+ width: listView.width
+
+ BasicButtonType {
+ id: restoreDefaultButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ defaultColor: AmneziaStyle.color.transparent
+ hoveredColor: AmneziaStyle.color.translucentWhite
+ pressedColor: AmneziaStyle.color.sheerWhite
+ disabledColor: AmneziaStyle.color.mutedGray
+ textColor: AmneziaStyle.color.paleGray
+ borderWidth: 1
+
+ text: qsTr("Restore default")
+
+ clickedFunc: function() {
+ var headerText = qsTr("Restore default DNS settings?")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ SettingsController.primaryDns = "1.1.1.1"
+ primaryDns.textField.text = SettingsController.primaryDns
+ SettingsController.secondaryDns = "1.0.0.1"
+ secondaryDns.textField.text = SettingsController.secondaryDns
+ PageController.showNotificationMessage(qsTr("Settings have been reset"))
+ }
+ var noButtonFunction = function() {
+ }
+
+ showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+ }
+ }
+
+ footer: ColumnLayout {
+ width: listView.width
+
+ BasicButtonType {
+ id: saveButton
+
+ Layout.fillWidth: true
+ Layout.margins: 16
+
+ text: qsTr("Save")
+
+ clickedFunc: function() {
+ if (primaryDns.textField.text !== SettingsController.primaryDns) {
+ SettingsController.primaryDns = primaryDns.textField.text
+ }
+ if (secondaryDns.textField.text !== SettingsController.secondaryDns) {
+ SettingsController.secondaryDns = secondaryDns.textField.text
+ }
+ PageController.showNotificationMessage(qsTr("Settings saved"))
+ }
+ }
+ }
+ }
+}
diff --git a/client/ui/qml/Pages2/PageSettingsLogging.qml b/client/ui/qml/Pages2/PageSettingsLogging.qml
index 5b20936c..fda58175 100644
--- a/client/ui/qml/Pages2/PageSettingsLogging.qml
+++ b/client/ui/qml/Pages2/PageSettingsLogging.qml
@@ -23,9 +23,15 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
+
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
}
- ListView {
+ ListViewType {
id: listView
anchors.top: backButton.bottom
@@ -33,10 +39,6 @@ PageType {
anchors.right: parent.right
anchors.left: parent.left
- property bool isFocusable: true
-
- ScrollBar.vertical: ScrollBarType {}
-
header: ColumnLayout {
width: listView.width
@@ -101,8 +103,7 @@ PageType {
}
model: logTypes
- clip: true
- reuseItems: true
+
snapMode: ListView.SnapOneItem
delegate: ColumnLayout {
diff --git a/client/ui/qml/Pages2/PageSettingsServerData.qml b/client/ui/qml/Pages2/PageSettingsServerData.qml
index 82552958..1a496b5b 100644
--- a/client/ui/qml/Pages2/PageSettingsServerData.qml
+++ b/client/ui/qml/Pages2/PageSettingsServerData.qml
@@ -18,10 +18,6 @@ PageType {
signal lastItemTabClickedSignal()
- onFocusChanged: content.isServerWithWriteAccess ?
- labelWithButton.forceActiveFocus() :
- labelWithButton3.forceActiveFocus()
-
Connections {
target: InstallController
@@ -63,218 +59,194 @@ PageType {
target: ServersModel
function onProcessedServerIndexChanged() {
- content.isServerWithWriteAccess = ServersModel.isProcessedServerHasWriteAccess()
+ listView.isServerWithWriteAccess = ServersModel.isProcessedServerHasWriteAccess()
}
}
- FlickableType {
- id: fl
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- contentHeight: content.height
+ ListViewType {
+ id: listView
- ColumnLayout {
- id: content
+ property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ anchors.fill: parent
- property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
+ model: serverActions
+
+ delegate: ColumnLayout {
+ width: listView.width
LabelWithButtonType {
- id: labelWithButton
- visible: content.isServerWithWriteAccess
Layout.fillWidth: true
- text: qsTr("Check the server for previously installed Amnezia services")
- descriptionText: qsTr("Add them to the application if they were not displayed")
+ visible: isVisible
+
+ text: title
+ descriptionText: description
+ textColor: tColor
clickedFunction: function() {
+ clickedHandler()
+ }
+ }
+
+ DividerType {
+ visible: isVisible
+ }
+ }
+ }
+
+ property list serverActions: [
+ check,
+ reboot,
+ remove,
+ clear,
+ reset,
+ switch_to_premium,
+ ]
+
+ QtObject {
+ id: check
+
+ property bool isVisible: true
+ readonly property string title: qsTr("Check the server for previously installed Amnezia services")
+ readonly property string description: qsTr("Add them to the application if they were not displayed")
+ readonly property var tColor: AmneziaStyle.color.paleGray
+ readonly property var clickedHandler: function() {
+ PageController.showBusyIndicator(true)
+ InstallController.scanServerForInstalledContainers()
+ PageController.showBusyIndicator(false)
+ }
+ }
+
+ QtObject {
+ id: reboot
+
+ property bool isVisible: true
+ readonly property string title: qsTr("Reboot server")
+ readonly property string description: ""
+ readonly property var tColor: AmneziaStyle.color.vibrantRed
+ readonly property var clickedHandler: function() {
+ var headerText = qsTr("Do you want to reboot the server?")
+ var descriptionText = qsTr("The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
+ PageController.showNotificationMessage(qsTr("Cannot reboot server during active connection"))
+ } else {
PageController.showBusyIndicator(true)
- InstallController.scanServerForInstalledContainers()
+ InstallController.rebootProcessedServer()
PageController.showBusyIndicator(false)
}
}
+ var noButtonFunction = function() {
- DividerType {
- visible: content.isServerWithWriteAccess
}
- LabelWithButtonType {
- id: labelWithButton2
- visible: content.isServerWithWriteAccess
- Layout.fillWidth: true
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+ }
- text: qsTr("Reboot server")
- textColor: AmneziaStyle.color.vibrantRed
+ QtObject {
+ id: remove
- clickedFunction: function() {
- var headerText = qsTr("Do you want to reboot the server?")
- var descriptionText = qsTr("The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
+ property bool isVisible: true
+ readonly property string title: qsTr("Remove server from application")
+ readonly property string description: ""
+ readonly property var tColor: AmneziaStyle.color.vibrantRed
+ readonly property var clickedHandler: function() {
+ var headerText = qsTr("Do you want to remove the server from application?")
+ var descriptionText = qsTr("All installed AmneziaVPN services will still remain on the server.")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
- var yesButtonFunction = function() {
- if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
- PageController.showNotificationMessage(qsTr("Cannot reboot server during active connection"))
- } else {
- PageController.showBusyIndicator(true)
- InstallController.rebootProcessedServer()
- PageController.showBusyIndicator(false)
- }
- if (!GC.isMobile()) {
- labelWithButton5.forceActiveFocus()
- }
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- labelWithButton2.forceActiveFocus()
- }
- }
-
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ var yesButtonFunction = function() {
+ if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
+ PageController.showNotificationMessage(qsTr("Cannot remove server during active connection"))
+ } else {
+ PageController.showBusyIndicator(true)
+ InstallController.removeProcessedServer()
+ PageController.showBusyIndicator(false)
}
}
+ var noButtonFunction = function() {
- DividerType {
- visible: content.isServerWithWriteAccess
}
- LabelWithButtonType {
- id: labelWithButton3
- Layout.fillWidth: true
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+ }
- text: qsTr("Remove server from application")
- textColor: AmneziaStyle.color.vibrantRed
+ QtObject {
+ id: clear
- clickedFunction: function() {
- var headerText = qsTr("Do you want to remove the server from application?")
- var descriptionText = qsTr("All installed AmneziaVPN services will still remain on the server.")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
+ property bool isVisible: true
+ readonly property string title: qsTr("Clear server from Amnezia software")
+ readonly property string description: ""
+ readonly property var tColor: AmneziaStyle.color.vibrantRed
+ readonly property var clickedHandler: function() {
+ var headerText = qsTr("Do you want to clear server from Amnezia software?")
+ var descriptionText = qsTr("All users whom you shared a connection with will no longer be able to connect to it.")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
- var yesButtonFunction = function() {
- if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
- PageController.showNotificationMessage(qsTr("Cannot remove server during active connection"))
- } else {
- PageController.showBusyIndicator(true)
- InstallController.removeProcessedServer()
- PageController.showBusyIndicator(false)
- }
- if (!GC.isMobile()) {
- labelWithButton5.forceActiveFocus()
- }
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- labelWithButton3.forceActiveFocus()
- }
- }
-
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ var yesButtonFunction = function() {
+ if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
+ PageController.showNotificationMessage(qsTr("Cannot clear server from Amnezia software during active connection"))
+ } else {
+ PageController.goToPage(PageEnum.PageDeinstalling)
+ InstallController.removeAllContainers()
}
}
+ var noButtonFunction = function() {
- DividerType {}
+ }
- LabelWithButtonType {
- id: labelWithButton4
- visible: content.isServerWithWriteAccess
- Layout.fillWidth: true
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+ }
- text: qsTr("Clear server from Amnezia software")
- textColor: AmneziaStyle.color.vibrantRed
+ QtObject {
+ id: reset
- clickedFunction: function() {
- var headerText = qsTr("Do you want to clear server from Amnezia software?")
- var descriptionText = qsTr("All users whom you shared a connection with will no longer be able to connect to it.")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
+ property bool isVisible: ServersModel.getProcessedServerData("isServerFromTelegramApi")
+ readonly property string title: qsTr("Reset API config")
+ readonly property string description: ""
+ readonly property var tColor: AmneziaStyle.color.vibrantRed
+ readonly property var clickedHandler: function() {
+ var headerText = qsTr("Do you want to reset API config?")
+ var descriptionText = ""
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
- var yesButtonFunction = function() {
- if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
- PageController.showNotificationMessage(qsTr("Cannot clear server from Amnezia software during active connection"))
- } else {
- PageController.goToPage(PageEnum.PageDeinstalling)
- InstallController.removeAllContainers()
- }
- if (!GC.isMobile()) {
- labelWithButton5.forceActiveFocus()
- }
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- labelWithButton4.forceActiveFocus()
- }
- }
-
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ var yesButtonFunction = function() {
+ if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
+ PageController.showNotificationMessage(qsTr("Cannot reset API config during active connection"))
+ } else {
+ PageController.showBusyIndicator(true)
+ InstallController.removeApiConfig(ServersModel.processedIndex)
+ PageController.showBusyIndicator(false)
}
}
+ var noButtonFunction = function() {
- DividerType {
- visible: content.isServerWithWriteAccess
}
- LabelWithButtonType {
- id: labelWithButton5
- visible: ServersModel.getProcessedServerData("isServerFromTelegramApi")
- Layout.fillWidth: true
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+ }
- text: qsTr("Reset API config")
- textColor: AmneziaStyle.color.vibrantRed
+ QtObject {
+ id: switch_to_premium
- clickedFunction: function() {
- var headerText = qsTr("Do you want to reset API config?")
- var descriptionText = ""
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
- PageController.showNotificationMessage(qsTr("Cannot reset API config during active connection"))
- } else {
- PageController.showBusyIndicator(true)
- InstallController.removeApiConfig(ServersModel.processedIndex)
- PageController.showBusyIndicator(false)
- }
-
- if (!GC.isMobile()) {
- labelWithButton5.forceActiveFocus()
- }
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- labelWithButton5.forceActiveFocus()
- }
- }
-
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
- }
-
- DividerType {
- visible: ServersModel.getProcessedServerData("isServerFromTelegramApi")
- }
-
- LabelWithButtonType {
- id: labelWithButton6
- visible: ServersModel.getProcessedServerData("isServerFromTelegramApi") && ServersModel.processedServerIsPremium
- Layout.fillWidth: true
-
- text: qsTr("Switch to the new Amnezia Premium subscription")
- textColor: AmneziaStyle.color.vibrantRed
-
- clickedFunction: function() {
- PageController.goToPageHome()
- ApiPremV1MigrationController.showMigrationDrawer()
- }
- }
-
- DividerType {
- visible: ServersModel.getProcessedServerData("isServerFromTelegramApi") && ServersModel.processedServerIsPremium
- }
+ property bool isVisible: ServersModel.getProcessedServerData("isServerFromTelegramApi")
+ readonly property string title: qsTr("Switch to the new Amnezia Premium subscription")
+ readonly property string description: ""
+ readonly property var tColor: AmneziaStyle.color.vibrantRed
+ readonly property var clickedHandler: function() {
+ PageController.goToPageHome()
+ ApiPremV1MigrationController.showMigrationDrawer()
}
}
}
diff --git a/client/ui/qml/Pages2/PageSettingsServerProtocol.qml b/client/ui/qml/Pages2/PageSettingsServerProtocol.qml
index fce9b2a3..a17149c9 100644
--- a/client/ui/qml/Pages2/PageSettingsServerProtocol.qml
+++ b/client/ui/qml/Pages2/PageSettingsServerProtocol.qml
@@ -21,249 +21,211 @@ PageType {
property bool isClearCacheVisible: ServersModel.isProcessedServerHasWriteAccess() && !ContainersModel.isServiceContainer(ContainersModel.getProcessedContainerIndex())
- ColumnLayout {
- id: header
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
-
anchors.topMargin: 20
-
- BackButtonType {
- id: backButton
+
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
+ }
- BaseHeaderType {
- Layout.fillWidth: true
- Layout.leftMargin: 16
- Layout.rightMargin: 16
- Layout.bottomMargin: 32
+ ListViewType {
+ id: listView
- headerText: ContainersModel.getProcessedContainerName() + qsTr(" settings")
- }
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
- ListView {
- id: protocols
- Layout.fillWidth: true
- height: protocols.contentItem.height
- clip: true
- interactive: true
+ header: ColumnLayout {
+ width: listView.width
- property bool isFocusable: true
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ Layout.bottomMargin: 32
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
- model: ProtocolsModel
-
- delegate: Item {
- implicitWidth: protocols.width
- implicitHeight: delegateContent.implicitHeight
-
- ColumnLayout {
- id: delegateContent
-
- anchors.fill: parent
-
- property bool isClientSettingsVisible: protocolIndex === ProtocolEnum.WireGuard || protocolIndex === ProtocolEnum.Awg
- property bool isServerSettingsVisible: ServersModel.isProcessedServerHasWriteAccess()
-
- LabelWithButtonType {
- id: clientSettings
-
- Layout.fillWidth: true
-
- text: protocolName + qsTr(" connection settings")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
- visible: delegateContent.isClientSettingsVisible
-
- clickedFunction: function() {
- if (isClientProtocolExists) {
- switch (protocolIndex) {
- case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- }
- PageController.goToPage(clientProtocolPage);
- } else {
- PageController.showNotificationMessage(qsTr("Click the \"connect\" button to create a connection configuration"))
- }
- }
-
- MouseArea {
- anchors.fill: clientSettings
- cursorShape: Qt.PointingHandCursor
- enabled: false
- }
- }
-
- DividerType {
- visible: delegateContent.isClientSettingsVisible
- }
-
- LabelWithButtonType {
- id: serverSettings
-
- Layout.fillWidth: true
-
- text: protocolName + qsTr(" server settings")
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
- visible: delegateContent.isServerSettingsVisible
-
- clickedFunction: function() {
- switch (protocolIndex) {
- case ProtocolEnum.OpenVpn: OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.ShadowSocks: ShadowSocksConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.Cloak: CloakConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.Xray: XrayConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.Sftp: SftpConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- case ProtocolEnum.Socks5Proxy: Socks5ProxyConfigModel.updateModel(ProtocolsModel.getConfig()); break;
- }
- PageController.goToPage(serverProtocolPage);
- }
-
- MouseArea {
- anchors.fill: serverSettings
- cursorShape: Qt.PointingHandCursor
- enabled: false
- }
- }
-
- DividerType {
- visible: delegateContent.isServerSettingsVisible
- }
- }
- }
-
- footer: ColumnLayout {
- width: header.width
-
- LabelWithButtonType {
- id: clearCacheButton
-
- Layout.fillWidth: true
-
- visible: root.isClearCacheVisible
-
- text: qsTr("Clear profile")
-
- clickedFunction: function() {
- var headerText = qsTr("Clear %1 profile?").arg(ContainersModel.getProcessedContainerName())
- var descriptionText = qsTr("The connection configuration will be deleted for this device only")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
- var message = qsTr("Unable to clear %1 profile while there is an active connection").arg(ContainersModel.getProcessedContainerName())
- PageController.showNotificationMessage(message)
- return
- }
-
- PageController.showBusyIndicator(true)
- InstallController.clearCachedProfile()
- PageController.showBusyIndicator(false)
- }
- var noButtonFunction = function() {
- // if (!GC.isMobile()) {
- // focusItem.forceActiveFocus()
- // }
- }
-
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
-
- MouseArea {
- anchors.fill: clearCacheButton
- cursorShape: Qt.PointingHandCursor
- enabled: false
- }
- }
-
- DividerType {
- Layout.fillWidth: true
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- visible: root.isClearCacheVisible
- }
-
- LabelWithButtonType {
- id: removeButton
-
- Layout.fillWidth: true
-
- visible: ServersModel.isProcessedServerHasWriteAccess()
-
- text: qsTr("Remove ")
- textColor: AmneziaStyle.color.vibrantRed
-
- clickedFunction: function() {
- var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
- var descriptionText = qsTr("All users with whom you shared a connection will no longer be able to connect to it.")
- var yesButtonText = qsTr("Continue")
- var noButtonText = qsTr("Cancel")
-
- var yesButtonFunction = function() {
- if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
- && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
- PageController.showNotificationMessage(qsTr("Cannot remove active container"))
- } else
- {
- PageController.goToPage(PageEnum.PageDeinstalling)
- InstallController.removeProcessedContainer()
- }
- }
- var noButtonFunction = function() {
- if (!GC.isMobile()) {
- focusItem.forceActiveFocus()
- }
- }
-
- showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
- }
-
- MouseArea {
- anchors.fill: removeButton
- cursorShape: Qt.PointingHandCursor
- enabled: false
- }
- }
-
- DividerType {
- Layout.fillWidth: true
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- visible: ServersModel.isProcessedServerHasWriteAccess()
- }
+ headerText: ContainersModel.getProcessedContainerName() + qsTr(" settings")
}
}
+ model: ProtocolsModel
+
+ delegate: ColumnLayout {
+ id: delegateContent
+
+ width: listView.width
+
+ property bool isClientSettingsVisible: (protocolIndex === ProtocolEnum.WireGuard) || (protocolIndex === ProtocolEnum.Awg)
+ property bool isServerSettingsVisible: ServersModel.isProcessedServerHasWriteAccess()
+
+ LabelWithButtonType {
+ id: clientSettings
+
+ Layout.fillWidth: true
+
+ text: protocolName + qsTr(" connection settings")
+ rightImageSource: "qrc:/images/controls/chevron-right.svg"
+ visible: delegateContent.isClientSettingsVisible
+
+ clickedFunction: function() {
+ if (isClientProtocolExists) {
+ switch (protocolIndex) {
+ case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ }
+ PageController.goToPage(clientProtocolPage);
+ } else {
+ PageController.showNotificationMessage(qsTr("Click the \"connect\" button to create a connection configuration"))
+ }
+ }
+
+ MouseArea {
+ anchors.fill: clientSettings
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
+ }
+
+ DividerType {
+ visible: delegateContent.isClientSettingsVisible
+ }
+
+ LabelWithButtonType {
+ id: serverSettings
+
+ Layout.fillWidth: true
+
+ text: protocolName + qsTr(" server settings")
+ rightImageSource: "qrc:/images/controls/chevron-right.svg"
+ visible: delegateContent.isServerSettingsVisible
+
+ clickedFunction: function() {
+ switch (protocolIndex) {
+ case ProtocolEnum.OpenVpn: OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.ShadowSocks: ShadowSocksConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.Cloak: CloakConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.Xray: XrayConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.Sftp: SftpConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ case ProtocolEnum.Socks5Proxy: Socks5ProxyConfigModel.updateModel(ProtocolsModel.getConfig()); break;
+ }
+ PageController.goToPage(serverProtocolPage);
+ }
+
+ MouseArea {
+ anchors.fill: serverSettings
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
+ }
+
+ DividerType {
+ visible: delegateContent.isServerSettingsVisible
+ }
+ }
+
+ footer: ColumnLayout {
+
+ width: listView.width
+
+ LabelWithButtonType {
+ id: clearCacheButton
+
+ Layout.fillWidth: true
+
+ visible: root.isClearCacheVisible
+
+ text: qsTr("Clear profile")
+
+ clickedFunction: function() {
+ var headerText = qsTr("Clear %1 profile?").arg(ContainersModel.getProcessedContainerName())
+ var descriptionText = qsTr("The connection configuration will be deleted for this device only")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
+ var message = qsTr("Unable to clear %1 profile while there is an active connection").arg(ContainersModel.getProcessedContainerName())
+ PageController.showNotificationMessage(message)
+ return
+ }
+
+ PageController.showBusyIndicator(true)
+ InstallController.clearCachedProfile()
+ PageController.showBusyIndicator(false)
+ }
+
+ var noButtonFunction = function() {
+ }
+
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+
+ MouseArea {
+ anchors.fill: clearCacheButton
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
+ }
+
+ DividerType {
+ visible: root.isClearCacheVisible
+ }
+
+ LabelWithButtonType {
+ id: removeButton
+
+ Layout.fillWidth: true
+
+ visible: ServersModel.isProcessedServerHasWriteAccess()
+
+ text: qsTr("Remove ")
+ textColor: AmneziaStyle.color.vibrantRed
+
+ clickedFunction: function() {
+ var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
+ var descriptionText = qsTr("All users with whom you shared a connection will no longer be able to connect to it.")
+ var yesButtonText = qsTr("Continue")
+ var noButtonText = qsTr("Cancel")
+
+ var yesButtonFunction = function() {
+ if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
+ && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
+ PageController.showNotificationMessage(qsTr("Cannot remove active container"))
+ } else
+ {
+ PageController.goToPage(PageEnum.PageDeinstalling)
+ InstallController.removeProcessedContainer()
+ }
+ }
+ var noButtonFunction = function() {
+
+ }
+
+ showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+ }
+
+ MouseArea {
+ anchors.fill: removeButton
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
+ }
+
+ DividerType {
+ visible: ServersModel.isProcessedServerHasWriteAccess()
+ }
+ }
}
}
-
diff --git a/client/ui/qml/Pages2/PageSettingsServersList.qml b/client/ui/qml/Pages2/PageSettingsServersList.qml
index 57e39ae8..f7222236 100644
--- a/client/ui/qml/Pages2/PageSettingsServersList.qml
+++ b/client/ui/qml/Pages2/PageSettingsServersList.qml
@@ -40,25 +40,20 @@ PageType {
}
}
- ListView {
+ ListViewType {
id: servers
objectName: "servers"
width: parent.width
anchors.top: header.bottom
anchors.topMargin: 16
+ anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
- height: 500
-
- property bool isFocusable: true
model: ServersModel
- clip: true
- reuseItems: true
-
delegate: Item {
implicitWidth: servers.width
implicitHeight: delegateContent.implicitHeight
diff --git a/client/ui/qml/Pages2/PageSettingsSplitTunneling.qml b/client/ui/qml/Pages2/PageSettingsSplitTunneling.qml
index 0cbed7c8..7d0ba599 100644
--- a/client/ui/qml/Pages2/PageSettingsSplitTunneling.qml
+++ b/client/ui/qml/Pages2/PageSettingsSplitTunneling.qml
@@ -161,7 +161,7 @@ PageType {
}
}
- ListView {
+ ListViewType {
id: listView
anchors.top: header.bottom
@@ -172,8 +172,6 @@ PageType {
enabled: root.pageEnabled
- property bool isFocusable: true
-
model: SortFilterProxyModel {
id: proxySitesModel
sourceModel: SitesModel
@@ -193,13 +191,7 @@ PageType {
]
}
- clip: true
-
- reuseItems: true
-
delegate: ColumnLayout {
- id: delegateContent
-
width: listView.width
LabelWithButtonType {
@@ -236,7 +228,6 @@ PageType {
}
}
-
Rectangle {
anchors.fill: addSiteButton
anchors.bottomMargin: -24
@@ -286,8 +277,8 @@ PageType {
moreActionsDrawer.openTriggered()
}
- Keys.onReturnPressed: this.clicked()
- Keys.onEnterPressed: this.clicked()
+ Keys.onReturnPressed: addSiteButtonImage.clicked()
+ Keys.onEnterPressed: addSiteButtonImage.clicked()
}
}
@@ -351,7 +342,7 @@ PageType {
}
DividerType {}
-
+
LabelWithButtonType {
id: clearSitesButton
Layout.fillWidth: true
@@ -402,22 +393,24 @@ PageType {
backButtonFunction: function() {
importSitesDrawer.closeTriggered()
}
+
+ onFocusChanged: {
+ if (this.activeFocus) {
+ importSitesDrawerListView.positionViewAtBeginning()
+ }
+ }
}
- FlickableType {
+ ListViewType {
+ id: importSitesDrawerListView
+
anchors.top: importSitesDrawerBackButton.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
- contentHeight: importSitesDrawerContent.height
-
- ColumnLayout {
- id: importSitesDrawerContent
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ header: ColumnLayout {
+ width: importSitesDrawerListView.width
Header2Type {
Layout.fillWidth: true
@@ -425,49 +418,67 @@ PageType {
headerText: qsTr("Import a list of sites")
}
+ }
+
+ model: importOptions
+
+ delegate: ColumnLayout {
+ width: importSitesDrawerListView.width
LabelWithButtonType {
- id: importSitesButton2
Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- text: qsTr("Replace site list")
+ text: title
clickedFunction: function() {
- var fileName = SystemController.getFileName(qsTr("Open sites file"),
- qsTr("Sites files (*.json)"))
- if (fileName !== "") {
- importSitesDrawerContent.importSites(fileName, true)
- }
+ clickedHandler()
}
}
DividerType {}
-
- LabelWithButtonType {
- id: importSitesButton3
- Layout.fillWidth: true
- text: qsTr("Add imported sites to existing ones")
-
- clickedFunction: function() {
- var fileName = SystemController.getFileName(qsTr("Open sites file"),
- qsTr("Sites files (*.json)"))
- if (fileName !== "") {
- importSitesDrawerContent.importSites(fileName, false)
- }
- }
- }
-
- function importSites(fileName, replaceExistingSites) {
- PageController.showBusyIndicator(true)
- SitesController.importSites(fileName, replaceExistingSites)
- PageController.showBusyIndicator(false)
- importSitesDrawer.closeTriggered()
- moreActionsDrawer.closeTriggered()
- }
-
- DividerType {}
}
}
}
}
+
+ property list importOptions: [
+ replaceOption,
+ addOption,
+ ]
+
+ QtObject {
+ id: replaceOption
+
+ readonly property string title: qsTr("Replace site list")
+ readonly property var clickedHandler: function() {
+ var fileName = SystemController.getFileName(qsTr("Open sites file"),
+ qsTr("Sites files (*.json)"))
+ if (fileName !== "") {
+ root.importSites(fileName, true)
+ }
+ }
+ }
+
+ QtObject {
+ id: addOption
+
+ readonly property string title: qsTr("Add imported sites to existing ones")
+ readonly property var clickedHandler: function() {
+ var fileName = SystemController.getFileName(qsTr("Open sites file"),
+ qsTr("Sites files (*.json)"))
+ if (fileName !== "") {
+ root.importSites(fileName, false)
+ }
+ }
+ }
+
+ function importSites(fileName, replaceExistingSites) {
+ PageController.showBusyIndicator(true)
+ SitesController.importSites(fileName, replaceExistingSites)
+ PageController.showBusyIndicator(false)
+ importSitesDrawer.closeTriggered()
+ moreActionsDrawer.closeTriggered()
+ }
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml b/client/ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml
index cfc07fd1..1f76c97d 100644
--- a/client/ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml
@@ -1,146 +1,177 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import QtQuick.Dialogs
-
-import PageEnum 1.0
-import Style 1.0
-
-import "./"
-import "../Controls2"
-import "../Controls2/TextTypes"
-import "../Config"
-import "../Components"
-
-PageType {
- id: root
-
- FlickableType {
- id: fl
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- contentHeight: content.height + continueButton.implicitHeight + continueButton.anchors.bottomMargin + continueButton.anchors.topMargin
-
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- spacing: 0
-
- BackButtonType {
- id: backButton
- Layout.topMargin: 20
- }
-
- BaseHeaderType {
- Layout.fillWidth: true
- Layout.topMargin: 8
- Layout.rightMargin: 16
- Layout.leftMargin: 16
- Layout.bottomMargin: 32
-
- headerText: ApiServicesModel.getSelectedServiceData("name")
- descriptionText: ApiServicesModel.getSelectedServiceData("serviceDescription")
- }
-
- LabelWithImageType {
- Layout.fillWidth: true
- Layout.margins: 16
-
- imageSource: "qrc:/images/controls/map-pin.svg"
- leftText: qsTr("For the region")
- rightText: ApiServicesModel.getSelectedServiceData("region")
- }
-
- LabelWithImageType {
- Layout.fillWidth: true
- Layout.margins: 16
-
- imageSource: "qrc:/images/controls/tag.svg"
- leftText: qsTr("Price")
- rightText: ApiServicesModel.getSelectedServiceData("price")
- }
-
- LabelWithImageType {
- Layout.fillWidth: true
- Layout.margins: 16
-
- imageSource: "qrc:/images/controls/history.svg"
- leftText: qsTr("Work period")
- rightText: ApiServicesModel.getSelectedServiceData("timeLimit")
-
- visible: rightText !== ""
- }
-
- LabelWithImageType {
- Layout.fillWidth: true
- Layout.margins: 16
-
- imageSource: "qrc:/images/controls/gauge.svg"
- leftText: qsTr("Speed")
- rightText: ApiServicesModel.getSelectedServiceData("speed")
- }
-
- LabelWithImageType {
- Layout.fillWidth: true
- Layout.margins: 16
-
- imageSource: "qrc:/images/controls/info.svg"
- leftText: qsTr("Features")
- rightText: ""
- }
-
- ParagraphTextType {
- Layout.fillWidth: true
- Layout.rightMargin: 16
- Layout.leftMargin: 16
-
- onLinkActivated: function(link) {
- Qt.openUrlExternally(link)
- }
- textFormat: Text.RichText
- text: {
- var text = ApiServicesModel.getSelectedServiceData("features")
- return text.replace("%1", LanguageModel.getCurrentSiteUrl("free"))
- }
-
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.NoButton
- cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
- }
- }
- }
- }
-
- BasicButtonType {
- id: continueButton
-
- anchors.right: parent.right
- anchors.left: parent.left
- anchors.bottom: parent.bottom
-
- anchors.topMargin: 32
- anchors.rightMargin: 16
- anchors.leftMargin: 16
- anchors.bottomMargin: 32
-
- text: qsTr("Connect")
-
- clickedFunc: function() {
- var endpoint = ApiServicesModel.getStoreEndpoint()
- if (endpoint !== undefined && endpoint !== "") {
- Qt.openUrlExternally(endpoint)
- PageController.closePage()
- PageController.closePage()
- } else {
- PageController.showBusyIndicator(true)
- ApiConfigsController.importServiceFromGateway()
- PageController.showBusyIndicator(false)
- }
- }
- }
-}
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Dialogs
+
+import PageEnum 1.0
+import Style 1.0
+
+import "./"
+import "../Controls2"
+import "../Controls2/TextTypes"
+import "../Config"
+import "../Components"
+
+PageType {
+ id: root
+
+ BackButtonType {
+ id: backButton
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
+
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
+ }
+
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+
+ header: ColumnLayout {
+ width: listView.width
+
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.topMargin: 8
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.bottomMargin: 32
+
+ headerText: ApiServicesModel.getSelectedServiceData("name")
+ descriptionText: ApiServicesModel.getSelectedServiceData("serviceDescription")
+ }
+ }
+
+ model: inputFields
+ spacing: 0
+
+ delegate: ColumnLayout {
+ width: listView.width
+
+ LabelWithImageType {
+ Layout.fillWidth: true
+ Layout.margins: 16
+
+ imageSource: imagePath
+ leftText: lText
+ rightText: rText
+ }
+ }
+
+ footer: ColumnLayout {
+ width: listView.width
+
+ spacing: 0
+
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ onLinkActivated: function(link) {
+ Qt.openUrlExternally(link)
+ }
+ textFormat: Text.RichText
+ text: {
+ var text = ApiServicesModel.getSelectedServiceData("features")
+ return text.replace("%1", LanguageModel.getCurrentSiteUrl("free"))
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.NoButton
+ cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
+ }
+ }
+
+ BasicButtonType {
+ id: continueButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.bottomMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Connect")
+
+ clickedFunc: function() {
+ var endpoint = ApiServicesModel.getStoreEndpoint()
+ if (endpoint !== undefined && endpoint !== "") {
+ Qt.openUrlExternally(endpoint)
+ PageController.closePage()
+ PageController.closePage()
+ } else {
+ PageController.showBusyIndicator(true)
+ ApiConfigsController.importServiceFromGateway()
+ PageController.showBusyIndicator(false)
+ }
+ }
+ }
+ }
+ }
+
+ property list inputFields: [
+ region,
+ price,
+ timeLimit,
+ speed,
+ features
+ ]
+
+ QtObject {
+ id: region
+
+ readonly property string imagePath: "qrc:/images/controls/map-pin.svg"
+ readonly property string lText: qsTr("For the region")
+ readonly property string rText: ApiServicesModel.getSelectedServiceData("region")
+ property bool isVisible: true
+ }
+
+ QtObject {
+ id: price
+
+ readonly property string imagePath: "qrc:/images/controls/tag.svg"
+ readonly property string lText: qsTr("Price")
+ readonly property string rText: ApiServicesModel.getSelectedServiceData("price")
+ property bool isVisible: true
+ }
+
+ QtObject {
+ id: timeLimit
+
+ readonly property string imagePath: "qrc:/images/controls/history.svg"
+ readonly property string lText: qsTr("Work period")
+ readonly property string rText: ApiServicesModel.getSelectedServiceData("timeLimit")
+ property bool isVisible: rText !== ""
+ }
+
+ QtObject {
+ id: speed
+
+ readonly property string imagePath: "qrc:/images/controls/gauge.svg"
+ readonly property string lText: qsTr("Speed")
+ readonly property string rText: ApiServicesModel.getSelectedServiceData("speed")
+ property bool isVisible: true
+ }
+
+ QtObject {
+ id: features
+
+ readonly property string imagePath: "qrc:/images/controls/info.svg"
+ readonly property string lText: qsTr("Features")
+ readonly property string rText: ""
+ property bool isVisible: true
+ }
+}
diff --git a/client/ui/qml/Pages2/PageSetupWizardApiServicesList.qml b/client/ui/qml/Pages2/PageSetupWizardApiServicesList.qml
index 207c305e..51fdee36 100644
--- a/client/ui/qml/Pages2/PageSetupWizardApiServicesList.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardApiServicesList.qml
@@ -14,86 +14,77 @@ import "../Config"
PageType {
id: root
- ColumnLayout {
- id: header
+ BackButtonType {
+ id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
+ Layout.topMargin: 20
- spacing: 0
-
- BackButtonType {
- id: backButton
- Layout.topMargin: 20
- }
-
- BaseHeaderType {
- Layout.fillWidth: true
- Layout.topMargin: 8
- Layout.rightMargin: 16
- Layout.leftMargin: 16
- Layout.bottomMargin: 16
-
- headerText: qsTr("VPN by Amnezia")
- descriptionText: qsTr("Choose a VPN service that suits your needs.")
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
}
}
- ListView {
- id: servicesListView
+ ListViewType {
+ id: listView
- anchors.top: header.bottom
+ anchors.top: backButton.bottom
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.topMargin: 16
- spacing: 0
- property bool isFocusable: true
-
- clip: true
- reuseItems: true
+ header: ColumnLayout {
+ width: listView.width
+
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.bottomMargin: 24
+
+ headerText: qsTr("VPN by Amnezia")
+ descriptionText: qsTr("Choose a VPN service that suits your needs.")
+ }
+ }
+
+ spacing: 0
model: ApiServicesModel
- ScrollBar.vertical: ScrollBarType {}
+ delegate: ColumnLayout {
- delegate: Item {
- implicitWidth: servicesListView.width
- implicitHeight: delegateContent.implicitHeight
+ width: listView.width
enabled: isServiceAvailable
- ColumnLayout {
- id: delegateContent
+ CardWithIconsType {
+ id: card
- anchors.fill: parent
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.bottomMargin: 16
- CardWithIconsType {
- id: card
+ headerText: name
+ bodyText: cardDescription
+ footerText: price
- Layout.fillWidth: true
- Layout.rightMargin: 16
- Layout.leftMargin: 16
- Layout.bottomMargin: 16
+ rightImageSource: "qrc:/images/controls/chevron-right.svg"
- headerText: name
- bodyText: cardDescription
- footerText: price
-
- rightImageSource: "qrc:/images/controls/chevron-right.svg"
-
- onClicked: {
- if (isServiceAvailable) {
- ApiServicesModel.setServiceIndex(index)
- PageController.goToPage(PageEnum.PageSetupWizardApiServiceInfo)
- }
+ onClicked: {
+ if (isServiceAvailable) {
+ ApiServicesModel.setServiceIndex(index)
+ PageController.goToPage(PageEnum.PageSetupWizardApiServiceInfo)
}
-
- Keys.onEnterPressed: this.clicked()
- Keys.onReturnPressed: this.clicked()
}
+
+ Keys.onEnterPressed: clicked()
+ Keys.onReturnPressed: clicked()
}
}
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
index 520dc5d3..f88745d4 100644
--- a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
@@ -27,21 +27,11 @@ PageType {
}
}
- ListView {
+ ListViewType {
id: listView
anchors.fill: parent
- property bool isFocusable: true
-
- ScrollBar.vertical: ScrollBarType {}
-
- model: variants
-
- clip: true
-
- reuseItems: true
-
header: ColumnLayout {
width: listView.width
@@ -216,6 +206,8 @@ PageType {
}
}
+ model: variants
+
delegate: ColumnLayout {
width: listView.width
diff --git a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml
index fd9404e0..6a30dbb7 100644
--- a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml
@@ -28,41 +28,14 @@ PageType {
}
}
- ListView {
+ ListViewType {
id: listView
+
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
- property bool isFocusable: true
-
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
- }
-
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
-
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
-
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
-
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
-
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
- ScrollBar.vertical: ScrollBarType {}
-
header: ColumnLayout {
width: listView.width
@@ -78,8 +51,6 @@ PageType {
model: inputFields
spacing: 16
- clip: true
- reuseItems: true
delegate: ColumnLayout {
width: listView.width
diff --git a/client/ui/qml/Pages2/PageSetupWizardEasy.qml b/client/ui/qml/Pages2/PageSetupWizardEasy.qml
index 599464cf..9bc5cf3f 100644
--- a/client/ui/qml/Pages2/PageSetupWizardEasy.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardEasy.qml
@@ -20,6 +20,7 @@ PageType {
SortFilterProxyModel {
id: proxyContainersModel
+
sourceModel: ContainersModel
filters: [
ValueFilter {
@@ -40,107 +41,98 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
+
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
}
- FlickableType {
- id: fl
+ ButtonGroup {
+ id: buttonGroup
+ }
+
+ ListViewType {
+ id: listView
+
+ property int dockerContainer
+ property int containerDefaultPort
+ property int containerDefaultTransportProto
+
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight + setupLaterButton.anchors.bottomMargin
+ anchors.left: parent.left
+ anchors.right: parent.right
- Column {
- id: content
+ spacing: 16
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.rightMargin: 16
- anchors.leftMargin: 16
+ header: ColumnLayout {
+ width: listView.width
spacing: 16
BaseHeaderType {
id: header
- implicitWidth: parent.width
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.bottomMargin: 16
+
headerTextMaximumLineCount: 10
headerText: qsTr("Choose Installation Type")
}
+ }
- ButtonGroup {
- id: buttonGroup
- }
+ model: proxyContainersModel
+ currentIndex: 0
- ListView {
- id: containers
- width: parent.width
- height: containers.contentItem.height
- spacing: 16
+ delegate: ColumnLayout {
+ width: listView.width
- currentIndex: 0
- clip: true
- interactive: false
- model: proxyContainersModel
+ CardType {
+ id: card
- property int dockerContainer
- property int containerDefaultPort
- property int containerDefaultTransportProto
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.bottomMargin: 16
- property bool isFocusable: true
+ headerText: easySetupHeader
+ bodyText: easySetupDescription
- delegate: Item {
- implicitWidth: containers.width
- implicitHeight: delegateContent.implicitHeight
+ ButtonGroup.group: buttonGroup
- ColumnLayout {
- id: delegateContent
+ onClicked: function() {
+ isEasySetup = true
+ var defaultContainerProto = ContainerProps.defaultProtocol(dockerContainer)
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- CardType {
- id: card
-
- Layout.fillWidth: true
-
- headerText: easySetupHeader
- bodyText: easySetupDescription
-
- ButtonGroup.group: buttonGroup
-
- onClicked: function() {
- isEasySetup = true
- var defaultContainerProto = ContainerProps.defaultProtocol(dockerContainer)
-
- containers.dockerContainer = dockerContainer
- containers.containerDefaultPort = ProtocolProps.getPortForInstall(defaultContainerProto)
- containers.containerDefaultTransportProto = ProtocolProps.defaultTransportProto(defaultContainerProto)
- }
-
- Keys.onEnterPressed: this.clicked()
- Keys.onReturnPressed: this.clicked()
- }
- }
+ listView.dockerContainer = dockerContainer
+ listView.containerDefaultPort = ProtocolProps.getPortForInstall(defaultContainerProto)
+ listView.containerDefaultTransportProto = ProtocolProps.defaultTransportProto(defaultContainerProto)
}
- Component.onCompleted: {
- var item = containers.itemAtIndex(containers.currentIndex)
- if (item !== null) {
- var button = item.children[0].children[0]
- button.checked = true
- button.clicked()
- }
- }
+ Keys.onReturnPressed: this.clicked()
+ Keys.onEnterPressed: this.clicked()
}
+ }
+
+ footer: ColumnLayout {
+ width: listView.width
+ spacing: 16
DividerType {
- implicitWidth: parent.width
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
}
CardType {
- implicitWidth: parent.width
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
headerText: qsTr("Manual")
bodyText: qsTr("Choose a VPN protocol")
@@ -149,6 +141,7 @@ PageType {
onClicked: function() {
isEasySetup = false
+ checked = true
}
Keys.onEnterPressed: this.clicked()
@@ -158,19 +151,19 @@ PageType {
BasicButtonType {
id: continueButton
- implicitWidth: parent.width
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
text: qsTr("Continue")
-
- parentFlickable: fl
clickedFunc: function() {
if (root.isEasySetup) {
- ContainersModel.setProcessedContainerIndex(containers.dockerContainer)
+ ContainersModel.setProcessedContainerIndex(listView.dockerContainer)
PageController.goToPage(PageEnum.PageSetupWizardInstalling)
- InstallController.install(containers.dockerContainer,
- containers.containerDefaultPort,
- containers.containerDefaultTransportProto)
+ InstallController.install(listView.dockerContainer,
+ listView.containerDefaultPort,
+ listView.containerDefaultTransportProto)
} else {
PageController.goToPage(PageEnum.PageSetupWizardProtocols)
}
@@ -180,9 +173,11 @@ PageType {
BasicButtonType {
id: setupLaterButton
- implicitWidth: parent.width
- anchors.topMargin: 8
- anchors.bottomMargin: 24
+ Layout.fillWidth: true
+ Layout.topMargin: 8
+ Layout.bottomMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.translucentWhite
@@ -191,9 +186,6 @@ PageType {
textColor: AmneziaStyle.color.paleGray
borderWidth: 1
- Keys.onTabPressed: lastItemTabClicked(focusItem)
- parentFlickable: fl
-
visible: {
if (PageController.isTriggeredByConnectButton()) {
PageController.setTriggeredByConnectButton(false)
@@ -211,5 +203,15 @@ PageType {
}
}
}
+
+ Component.onCompleted: {
+ var item = listView.itemAtIndex(listView.currentIndex)
+ if (item !== null) {
+ var button = item.children[0]
+ button.checked = true
+ button.clicked()
+ }
+ }
}
}
+
diff --git a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml
index 822931b8..efabeb9f 100644
--- a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml
@@ -85,92 +85,76 @@ PageType {
]
}
- FlickableType {
+ ListViewType {
+ id: listView
+
anchors.fill: parent
- contentHeight: content.height
- Column {
- id: content
+ currentIndex: -1
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ model: proxyContainersModel
- spacing: 16
+ delegate: ColumnLayout {
+ width: listView.width
- ListView {
- id: container
- width: parent.width
- height: container.contentItem.height
- currentIndex: -1
- clip: true
- interactive: false
- model: proxyContainersModel
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.topMargin: 20
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- delegate: Item {
- implicitWidth: container.width
- implicitHeight: delegateContent.implicitHeight
+ headerText: qsTr("Installing")
+ descriptionText: name
+ }
- ColumnLayout {
- id: delegateContent
+ ProgressBarType {
+ id: progressBar
- anchors.fill: parent
- anchors.rightMargin: 16
- anchors.leftMargin: 16
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- BaseHeaderType {
- Layout.fillWidth: true
- Layout.topMargin: 20
+ Timer {
+ id: timer
- headerText: qsTr("Installing")
- descriptionText: name
- }
-
- ProgressBarType {
- id: progressBar
-
- Layout.fillWidth: true
- Layout.topMargin: 32
-
- Timer {
- id: timer
-
- interval: 300
- repeat: true
- running: root.isTimerRunning
- onTriggered: {
- progressBar.value += 0.003
- }
- }
- }
-
- ParagraphTextType {
- id: progressText
-
- Layout.fillWidth: true
- Layout.topMargin: 8
-
- text: root.progressBarText
- }
-
- BasicButtonType {
- id: cancelIntallationButton
-
- Layout.fillWidth: true
- Layout.topMargin: 24
-
- visible: root.isCancelButtonVisible
-
- text: qsTr("Cancel installation")
-
- clickedFunc: function() {
- InstallController.cancelInstallation()
- PageController.showBusyIndicator(true)
- }
- }
+ interval: 300
+ repeat: true
+ running: root.isTimerRunning
+ onTriggered: {
+ progressBar.value += 0.003
}
}
}
+
+ ParagraphTextType {
+ id: progressText
+
+ Layout.fillWidth: true
+ Layout.topMargin: 8
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: root.progressBarText
+ }
+
+ BasicButtonType {
+ id: cancelIntallationButton
+
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ visible: root.isCancelButtonVisible
+
+ text: qsTr("Cancel installation")
+
+ clickedFunc: function() {
+ InstallController.cancelInstallation()
+ PageController.showBusyIndicator(true)
+ }
+ }
}
}
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml b/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml
index ac7fc4b2..4d914a1d 100644
--- a/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml
@@ -29,256 +29,239 @@ PageType {
]
}
- FlickableType {
- anchors.fill: parent
- contentHeight: content.height
+ BackButtonType {
+ id: backButton
- Column {
- id: content
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
+ }
- ListView {
- id: processedContainerListView
- width: parent.width
- height: contentItem.height
- currentIndex: -1
- clip: true
- interactive: false
- model: proxyContainersModel
+ ListViewType {
+ id: listView
- property bool isFocusable: true
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
- Keys.onTabPressed: {
- FocusController.nextKeyTabItem()
+ currentIndex: -1
+
+ model: proxyContainersModel
+
+ delegate: ColumnLayout {
+ width: listView.width
+
+ BaseHeaderType {
+ id: header
+
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ headerText: qsTr("Installing %1").arg(name)
+ descriptionText: description
+ }
+
+ BasicButtonType {
+ id: showDetailsButton
+
+ Layout.topMargin: 16
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ implicitHeight: 32
+
+ defaultColor: AmneziaStyle.color.transparent
+ hoveredColor: AmneziaStyle.color.translucentWhite
+ pressedColor: AmneziaStyle.color.sheerWhite
+ disabledColor: AmneziaStyle.color.mutedGray
+ textColor: AmneziaStyle.color.goldenApricot
+
+ text: qsTr("More detailed")
+
+ clickedFunc: function() {
+ showDetailsDrawer.openTriggered()
}
+ }
- Keys.onBacktabPressed: {
- FocusController.previousKeyTabItem()
- }
+ DrawerType2 {
+ id: showDetailsDrawer
+ parent: root
- Keys.onUpPressed: {
- FocusController.nextKeyUpItem()
- }
+ anchors.fill: parent
+ expandedHeight: parent.height * 0.9
+ expandedStateContent: Item {
+ implicitHeight: showDetailsDrawer.expandedHeight
- Keys.onDownPressed: {
- FocusController.nextKeyDownItem()
- }
+ BackButtonType {
+ id: showDetailsBackButton
- Keys.onLeftPressed: {
- FocusController.nextKeyLeftItem()
- }
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 16
- Keys.onRightPressed: {
- FocusController.nextKeyRightItem()
- }
-
- delegate: Item {
- implicitWidth: processedContainerListView.width
- implicitHeight: (delegateContent.implicitHeight > root.height) ? delegateContent.implicitHeight : root.height
-
- property alias port:port
-
- ColumnLayout {
- id: delegateContent
-
- anchors.fill: parent
- anchors.rightMargin: 16
- anchors.leftMargin: 16
-
- BackButtonType {
- id: backButton
-
- Layout.topMargin: 20
- Layout.rightMargin: -16
- Layout.leftMargin: -16
+ backButtonFunction: function() {
+ showDetailsDrawer.closeTriggered()
}
+ }
- BaseHeaderType {
- id: header
+ ListViewType {
+ id: showDetailsListView
- Layout.fillWidth: true
+ anchors.top: showDetailsBackButton.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
- headerText: qsTr("Installing %1").arg(name)
- descriptionText: description
- }
+ header: ColumnLayout {
+ width: showDetailsListView.width
- BasicButtonType {
- id: showDetailsButton
+ Header2Type {
+ id: showDetailsDrawerHeader
- Layout.topMargin: 16
- Layout.leftMargin: -8
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
- implicitHeight: 32
-
- defaultColor: AmneziaStyle.color.transparent
- hoveredColor: AmneziaStyle.color.translucentWhite
- pressedColor: AmneziaStyle.color.sheerWhite
- disabledColor: AmneziaStyle.color.mutedGray
- textColor: AmneziaStyle.color.goldenApricot
-
- text: qsTr("More detailed")
- KeyNavigation.tab: transportProtoSelector
-
- clickedFunc: function() {
- showDetailsDrawer.openTriggered()
+ headerText: name
}
}
- DrawerType2 {
- id: showDetailsDrawer
- parent: root
+ model: 1 // fake model to force the ListView to be created without a model
- anchors.fill: parent
- expandedHeight: parent.height * 0.9
- expandedStateContent: Item {
- implicitHeight: showDetailsDrawer.expandedHeight
+ delegate: ColumnLayout {
+ width: showDetailsListView.width
- BackButtonType {
- id: showDetailsBackButton
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.bottomMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 16
+ text: detailedDescription
+ textFormat: Text.MarkdownText
+ }
- backButtonFunction: function() {
- showDetailsDrawer.closeTriggered()
- }
- }
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- FlickableType {
- id: fl
- anchors.top: showDetailsBackButton.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- contentHeight: {
- var emptySpaceHeight = parent.height - showDetailsBackButton.implicitHeight - showDetailsBackButton.anchors.topMargin
- return (showDetailsDrawerContent.height > emptySpaceHeight) ?
- showDetailsDrawerContent.height : emptySpaceHeight
- }
+ color: AmneziaStyle.color.transparent
+ }
+ }
- ColumnLayout {
- id: showDetailsDrawerContent
+ footer: ColumnLayout {
+ width: showDetailsListView.width
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.rightMargin: 16
- anchors.leftMargin: 16
+ BasicButtonType {
+ id: showDetailsCloseButton
+ Layout.fillWidth: true
+ Layout.bottomMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- Header2Type {
- id: showDetailsDrawerHeader
- Layout.fillWidth: true
- Layout.topMargin: 16
+ text: qsTr("Close")
- headerText: name
- }
-
- ParagraphTextType {
- Layout.fillWidth: true
- Layout.topMargin: 16
- Layout.bottomMargin: 16
-
- text: detailedDescription
- textFormat: Text.MarkdownText
- }
-
- Rectangle {
- Layout.fillHeight: true
- color: AmneziaStyle.color.transparent
- }
-
- BasicButtonType {
- id: showDetailsCloseButton
- Layout.fillWidth: true
- Layout.bottomMargin: 32
- parentFlickable: fl
-
- text: qsTr("Close")
-
- clickedFunc: function() {
- showDetailsDrawer.closeTriggered()
- }
- }
- }
+ clickedFunc: function() {
+ showDetailsDrawer.closeTriggered()
}
}
}
-
- ParagraphTextType {
- id: transportProtoHeader
-
- Layout.topMargin: 16
-
- text: qsTr("Network protocol")
- }
-
- TransportProtoSelector {
- id: transportProtoSelector
-
- Layout.fillWidth: true
- rootWidth: root.width
- }
-
- TextFieldWithHeaderType {
- id: port
-
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- headerText: qsTr("Port")
- textField.maximumLength: 5
- textField.validator: IntValidator { bottom: 1; top: 65535 }
- }
-
- Rectangle {
- Layout.fillHeight: true
- color: AmneziaStyle.color.transparent
- }
-
- BasicButtonType {
- id: installButton
-
- Layout.fillWidth: true
- Layout.bottomMargin: 32
-
- text: qsTr("Install")
-
- clickedFunc: function() {
- if (!port.textField.acceptableInput &&
- ContainerProps.containerTypeToString(dockerContainer) !== "torwebsite" &&
- ContainerProps.containerTypeToString(dockerContainer) !== "ikev2") {
- port.errorText = qsTr("The port must be in the range of 1 to 65535")
- return
- }
-
- PageController.goToPage(PageEnum.PageSetupWizardInstalling);
- InstallController.install(dockerContainer, port.textField.text, transportProtoSelector.currentIndex)
- }
- }
-
- Component.onCompleted: {
- var defaultContainerProto = ContainerProps.defaultProtocol(dockerContainer)
-
- if (ProtocolProps.defaultPort(defaultContainerProto) < 0) {
- port.visible = false
- } else {
- port.textField.text = ProtocolProps.getPortForInstall(defaultContainerProto)
- }
- transportProtoSelector.currentIndex = ProtocolProps.defaultTransportProto(defaultContainerProto)
-
- port.enabled = ProtocolProps.defaultPortChangeable(defaultContainerProto)
- var protocolSelectorVisible = ProtocolProps.defaultTransportProtoChangeable(defaultContainerProto)
- transportProtoSelector.visible = protocolSelectorVisible
- transportProtoHeader.visible = protocolSelectorVisible
- }
}
}
}
+
+ ParagraphTextType {
+ id: transportProtoHeader
+
+ Layout.topMargin: 16
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ text: qsTr("Network protocol")
+ }
+
+ TransportProtoSelector {
+ id: transportProtoSelector
+
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ rootWidth: root.width
+ }
+
+ TextFieldWithHeaderType {
+ id: port
+
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ headerText: qsTr("Port")
+ textField.maximumLength: 5
+ textField.validator: IntValidator { bottom: 1; top: 65535 }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ color: AmneziaStyle.color.transparent
+ }
+
+ BasicButtonType {
+ id: installButton
+
+ Layout.fillWidth: true
+ Layout.bottomMargin: 32
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+
+ text: qsTr("Install")
+
+ clickedFunc: function() {
+ if (!port.textField.acceptableInput &&
+ ContainerProps.containerTypeToString(dockerContainer) !== "torwebsite" &&
+ ContainerProps.containerTypeToString(dockerContainer) !== "ikev2") {
+ port.errorText = qsTr("The port must be in the range of 1 to 65535")
+ return
+ }
+
+ PageController.goToPage(PageEnum.PageSetupWizardInstalling);
+ InstallController.install(dockerContainer, port.textField.text, transportProtoSelector.currentIndex)
+ }
+ }
+
+ Component.onCompleted: {
+ var defaultContainerProto = ContainerProps.defaultProtocol(dockerContainer)
+
+ if (ProtocolProps.defaultPort(defaultContainerProto) < 0) {
+ port.visible = false
+ } else {
+ port.textField.text = ProtocolProps.getPortForInstall(defaultContainerProto)
+ }
+ transportProtoSelector.currentIndex = ProtocolProps.defaultTransportProto(defaultContainerProto)
+
+ port.enabled = ProtocolProps.defaultPortChangeable(defaultContainerProto)
+ var protocolSelectorVisible = ProtocolProps.defaultTransportProtoChangeable(defaultContainerProto)
+ transportProtoSelector.visible = protocolSelectorVisible
+ transportProtoHeader.visible = protocolSelectorVisible
+ }
}
}
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardProtocols.qml b/client/ui/qml/Pages2/PageSetupWizardProtocols.qml
index 7afab630..da1edee6 100644
--- a/client/ui/qml/Pages2/PageSetupWizardProtocols.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardProtocols.qml
@@ -42,19 +42,21 @@ PageType {
anchors.right: parent.right
anchors.topMargin: 20
+
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
}
- ListView {
+ ListViewType {
id: listView
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
- property bool isFocusable: true
-
- ScrollBar.vertical: ScrollBarType {}
-
header: ColumnLayout {
width: listView.width
@@ -72,9 +74,8 @@ PageType {
}
model: proxyContainersModel
- clip: true
+
spacing: 0
- reuseItems: true
snapMode: ListView.SnapToItem
delegate: ColumnLayout {
@@ -87,9 +88,9 @@ PageType {
descriptionText: description
rightImageSource: "qrc:/images/controls/chevron-right.svg"
- clickedFunction: function() {
- ContainersModel.setProcessedContainerIndex(proxyContainersModel.mapToSource(index))
- PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
+ clickedFunction: function () {
+ ContainersModel.setProcessedContainerIndex(proxyContainersModel.mapToSource(index));
+ PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings);
}
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardTextKey.qml b/client/ui/qml/Pages2/PageSetupWizardTextKey.qml
index 930efb57..3a0f7832 100644
--- a/client/ui/qml/Pages2/PageSetupWizardTextKey.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardTextKey.qml
@@ -13,25 +13,31 @@ import "../Config"
PageType {
id: root
- FlickableType {
- id: fl
+ BackButtonType {
+ id: backButton
+
anchors.top: parent.top
- anchors.bottom: parent.bottom
- contentHeight: content.height
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- spacing: 16
-
- BackButtonType {
- id: backButton
- Layout.topMargin: 20
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
}
+ }
+ }
+
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+
+ header: ColumnLayout {
+ width: listView.width
BaseHeaderType {
Layout.fillWidth: true
@@ -41,6 +47,13 @@ PageType {
headerText: qsTr("Connection key")
descriptionText: qsTr("A line that starts with vpn://...")
}
+ }
+
+ spacing: 16
+ model: 1 // fake model to force the ListView to be created without a model
+
+ delegate: ColumnLayout {
+ width: listView.width
TextFieldWithHeaderType {
id: textKey
@@ -60,23 +73,26 @@ PageType {
}
}
}
- }
- BasicButtonType {
- id: continueButton
+ footer: ColumnLayout {
+ width: listView.width
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.rightMargin: 16
- anchors.leftMargin: 16
- anchors.bottomMargin: 32
+ BasicButtonType {
+ id: continueButton
- text: qsTr("Continue")
+ Layout.fillWidth: true
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
+ Layout.topMargin: 16
+ Layout.bottomMargin: 32
- clickedFunc: function() {
- if (ImportController.extractConfigFromData(textKey.textField.text)) {
- PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
+ text: qsTr("Continue")
+
+ clickedFunc: function() {
+ if (ImportController.extractConfigFromData(textKey.textField.text)) {
+ PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
+ }
+ }
}
}
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml b/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml
index cfa9c90f..bffa66a2 100644
--- a/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml
@@ -23,6 +23,12 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
+
+ onActiveFocusChanged: {
+ if(backButton.enabled && backButton.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
}
Connections {
@@ -46,27 +52,29 @@ PageType {
}
}
- FlickableType {
- id: fl
+ ListViewType {
+ id: listView
+
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
- contentHeight: content.implicitHeight + connectButton.implicitHeight
+ anchors.right: parent.right
+ anchors.left: parent.left
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.rightMargin: 16
- anchors.leftMargin: 16
+ header: ColumnLayout {
+ width: listView.width
BaseHeaderType {
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
headerText: qsTr("New connection")
}
RowLayout {
Layout.topMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
spacing: 8
visible: fileName.text !== ""
@@ -88,7 +96,9 @@ PageType {
BasicButtonType {
id: showContentButton
Layout.topMargin: 16
- Layout.leftMargin: -8
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
implicitHeight: 32
defaultColor: AmneziaStyle.color.transparent
@@ -99,8 +109,6 @@ PageType {
text: showContent ? qsTr("Collapse content") : qsTr("Show content")
- parentFlickable: fl
-
clickedFunc: function() {
showContent = !showContent
}
@@ -108,16 +116,28 @@ PageType {
CheckBoxType {
id: cloakingCheckBox
+ objectName: "cloakingCheckBox"
visible: ImportController.isNativeWireGuardConfig()
Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
text: qsTr("Enable WireGuard obfuscation. It may be useful if WireGuard is blocked on your provider.")
}
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+
+ delegate: ColumnLayout { // TODO(CyAn84): add DelegateChooser after have migrated to 6.9
+ width: listView.width
WarningType {
- Layout.topMargin: 16
Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
textString: ImportController.getMaliciousWarningText()
textFormat: Qt.RichText
@@ -130,8 +150,10 @@ PageType {
}
WarningType {
- Layout.topMargin: 16
Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
textString: qsTr("Use connection codes only from sources you trust. Codes from public sources may have been created to intercept your data.")
@@ -140,7 +162,10 @@ PageType {
Rectangle {
Layout.fillWidth: true
+ Layout.topMargin: 16
Layout.bottomMargin: 48
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
implicitHeight: configContent.implicitHeight
@@ -161,34 +186,38 @@ PageType {
}
}
}
- }
- Rectangle {
- anchors.fill: columnContent
- anchors.bottomMargin: -24
- color: AmneziaStyle.color.midnightBlack
- opacity: 0.8
- }
+ footer: ColumnLayout {
+ width: listView.width
- ColumnLayout {
- id: columnContent
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.rightMargin: 16
- anchors.leftMargin: 16
+ BasicButtonType {
+ id: connectButton
- BasicButtonType {
- id: connectButton
- Layout.fillWidth: true
- Layout.bottomMargin: 32
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.bottomMargin: 32
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
- text: qsTr("Connect")
- clickedFunc: function() {
- if (cloakingCheckBox.checked) {
- ImportController.processNativeWireGuardConfig()
+ text: qsTr("Connect")
+ clickedFunc: function() {
+ const headerItem = listView.headerItem;
+ if (!headerItem) {
+ console.error("Header item not found in ListView")
+ return
+ }
+
+ const cloakingCheckBoxItem = listView.findChildWithObjectName(headerItem.children, "cloakingCheckBox");
+ if (!cloakingCheckBoxItem) {
+ console.error("cloakingCheckBox not found")
+ return
+ }
+
+ if (cloakingCheckBoxItem.checked) {
+ ImportController.processNativeWireGuardConfig()
+ }
+ ImportController.importConfig()
}
- ImportController.importConfig()
}
}
}
diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml
index 327b59b6..d0d2a4de 100644
--- a/client/ui/qml/Pages2/PageShare.qml
+++ b/client/ui/qml/Pages2/PageShare.qml
@@ -510,9 +510,6 @@ PageType {
text: qsTr("Share")
leftImageSource: "qrc:/images/controls/share-2.svg"
-
- parentFlickable: a
-
clickedFunc: function(){
if (clientNameTextField.textField.text !== "") {
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
diff --git a/client/ui/qml/Pages2/PageShareFullAccess.qml b/client/ui/qml/Pages2/PageShareFullAccess.qml
index 062d0d1b..8a6b7a28 100644
--- a/client/ui/qml/Pages2/PageShareFullAccess.qml
+++ b/client/ui/qml/Pages2/PageShareFullAccess.qml
@@ -1,150 +1,170 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import QtQuick.Dialogs
-
-import SortFilterProxyModel 0.2
-
-import PageEnum 1.0
-import ContainerProps 1.0
-import Style 1.0
-
-import "./"
-import "../Controls2"
-import "../Controls2/TextTypes"
-import "../Components"
-import "../Config"
-
-
-PageType {
- id: root
-
- BackButtonType {
- id: backButton
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 20
- }
-
- FlickableType {
- anchors.top: backButton.bottom
- anchors.bottom: parent.bottom
- contentHeight: content.height
-
- ColumnLayout {
- id: content
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
-
- anchors.rightMargin: 16
- anchors.leftMargin: 16
-
- spacing: 0
-
- BaseHeaderType {
- Layout.fillWidth: true
- Layout.topMargin: 24
-
- headerText: qsTr("Full access to the server and VPN")
- }
-
- ParagraphTextType {
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 24
-
- text: qsTr("We recommend that you use full access to the server only for your own additional devices.\n") +
- qsTr("If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. ")
- color: AmneziaStyle.color.mutedGray
- }
-
- DropDownType {
- id: serverSelector
-
- signal severSelectorIndexChanged
- property int currentIndex: 0
-
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- drawerHeight: 0.4375
- drawerParent: root
-
- descriptionText: qsTr("Server")
- headerText: qsTr("Server")
-
- listView: ListViewWithRadioButtonType {
- id: serverSelectorListView
-
- rootWidth: root.width
- imageSource: "qrc:/images/controls/check.svg"
-
- model: SortFilterProxyModel {
- id: proxyServersModel
- sourceModel: ServersModel
- filters: [
- ValueFilter {
- roleName: "hasWriteAccess"
- value: true
- }
- ]
- }
-
- clickedFunction: function() {
- handler()
-
- if (serverSelector.currentIndex !== serverSelectorListView.currentIndex) {
- serverSelector.currentIndex = serverSelectorListView.currentIndex
- }
-
- shareConnectionPage.headerText = qsTr("Accessing ") + serverSelector.text
- shareConnectionPage.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
- serverSelector.closeTriggered()
- }
-
- Component.onCompleted: {
- serverSelectorListView.currentIndex = ServersModel.isDefaultServerHasWriteAccess() ?
- proxyServersModel.mapFromSource(ServersModel.defaultIndex) : 0
- serverSelectorListView.triggerCurrentItem()
- }
-
- function handler() {
- serverSelector.text = selectedText
- ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
- }
- }
- }
-
- BasicButtonType {
- id: shareButton
- Layout.fillWidth: true
- Layout.topMargin: 40
-
- text: qsTr("Share")
- leftImageSource: "qrc:/images/controls/share-2.svg"
-
- clickedFunc: function() {
- PageController.showBusyIndicator(true)
-
- if (Qt.platform.os === "android" && !SystemController.isAuthenticated()) {
- PageController.showBusyIndicator(false)
- ExportController.exportErrorOccurred(qsTr("Access error!"))
- return
- } else {
- ExportController.generateFullAccessConfig()
- }
-
- PageController.showBusyIndicator(false)
-
- PageController.goToPage(PageEnum.PageShareConnection)
- }
- }
- }
- }
-
-}
-
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Dialogs
+
+import SortFilterProxyModel 0.2
+
+import PageEnum 1.0
+import ContainerProps 1.0
+import Style 1.0
+
+import "./"
+import "../Controls2"
+import "../Controls2/TextTypes"
+import "../Components"
+import "../Config"
+
+
+PageType {
+ id: root
+
+ BackButtonType {
+ id: backButton
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
+
+ onFocusChanged: {
+ if (this.activeFocus) {
+ listView.positionViewAtBeginning()
+ }
+ }
+ }
+
+ ListViewType {
+ id: listView
+
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+
+ header: ColumnLayout {
+ width: listView.width
+
+ BaseHeaderType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ Layout.topMargin: 24
+
+ headerText: qsTr("Full access to the server and VPN")
+ }
+
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+
+ text: qsTr("We recommend that you use full access to the server only for your own additional devices.\n") +
+ qsTr("If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. ")
+ color: AmneziaStyle.color.mutedGray
+ }
+
+ DropDownType {
+ id: serverSelector
+ objectName: "serverSelector"
+
+ signal severSelectorIndexChanged
+ property int currentIndex: 0
+
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ Layout.topMargin: 16
+
+ drawerHeight: 0.4375
+ drawerParent: root
+
+ descriptionText: qsTr("Server")
+ headerText: qsTr("Server")
+
+ listView: ListViewWithRadioButtonType {
+ id: serverSelectorListView
+
+ rootWidth: root.width
+ imageSource: "qrc:/images/controls/check.svg"
+
+ model: SortFilterProxyModel {
+ id: proxyServersModel
+ sourceModel: ServersModel
+ filters: [
+ ValueFilter {
+ roleName: "hasWriteAccess"
+ value: true
+ }
+ ]
+ }
+
+ clickedFunction: function() {
+ handler()
+
+ if (serverSelector.currentIndex !== serverSelectorListView.currentIndex) {
+ serverSelector.currentIndex = serverSelectorListView.currentIndex
+ }
+
+ shareConnectionPage.headerText = qsTr("Accessing ") + serverSelector.text
+ shareConnectionPage.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
+ serverSelector.closeTriggered()
+ }
+
+ Component.onCompleted: {
+ serverSelectorListView.currentIndex = ServersModel.isDefaultServerHasWriteAccess() ?
+ proxyServersModel.mapFromSource(ServersModel.defaultIndex) : 0
+ serverSelectorListView.triggerCurrentItem()
+ }
+
+ function handler() {
+ serverSelector.text = selectedText
+ ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
+ }
+ }
+ }
+ }
+
+ model: 1 // fake model to force the ListView to be created without a model
+ spacing: 0
+
+ delegate: ColumnLayout {
+ width: listView.width
+
+ BasicButtonType {
+ id: shareButton
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ text: qsTr("Share")
+ leftImageSource: "qrc:/images/controls/share-2.svg"
+
+ clickedFunc: function() {
+ PageController.showBusyIndicator(true)
+
+ if (Qt.platform.os === "android" && !SystemController.isAuthenticated()) {
+ PageController.showBusyIndicator(false)
+ ExportController.exportErrorOccurred(qsTr("Access error!"))
+ return
+ } else {
+ ExportController.generateFullAccessConfig()
+ }
+
+ PageController.showBusyIndicator(false)
+
+ PageController.goToPage(PageEnum.PageShareConnection)
+ }
+ }
+ }
+ }
+
+ ShareConnectionDrawer {
+ id: shareConnectionDrawer
+
+ anchors.fill: parent
+ }
+}