diff --git a/client/images/controls/edit-3.svg b/client/images/controls/edit-3.svg
new file mode 100644
index 00000000..4e1dc071
--- /dev/null
+++ b/client/images/controls/edit-3.svg
@@ -0,0 +1,4 @@
+
diff --git a/client/resources.qrc b/client/resources.qrc
index ca1674af..ca02df7d 100644
--- a/client/resources.qrc
+++ b/client/resources.qrc
@@ -234,5 +234,10 @@
ui/qml/Pages2/PageSettings.qml
ui/qml/Controls2/PageType.qml
ui/qml/Controls2/PopupType.qml
+ images/controls/edit-3.svg
+ ui/qml/Pages2/PageSettingsData.qml
+ ui/qml/Components/PageSettingsContainersListView.qml
+ ui/qml/Controls2/TextTypes/ListItemTitleType.qml
+ ui/qml/Controls2/DividerType.qml
diff --git a/client/ui/models/containers_model.cpp b/client/ui/models/containers_model.cpp
index 6a999011..4dc7010e 100644
--- a/client/ui/models/containers_model.cpp
+++ b/client/ui/models/containers_model.cpp
@@ -1,5 +1,7 @@
#include "containers_model.h"
+#include "core/servercontroller.h"
+
ContainersModel::ContainersModel(std::shared_ptr settings, QObject *parent) : m_settings(settings), QAbstractListModel(parent)
{
}
@@ -106,6 +108,22 @@ int ContainersModel::getCurrentlyInstalledContainerIndex()
return m_currentlyInstalledContainerIndex;
}
+void ContainersModel::removeAllContainers()
+{
+
+ ServerController serverController(m_settings);
+ auto errorCode = serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex));
+
+ if (errorCode == ErrorCode::NoError) {
+ beginResetModel();
+ m_settings->setContainers(m_currentlyProcessedServerIndex, {});
+ m_settings->setDefaultContainer(m_currentlyProcessedServerIndex, DockerContainer::None);
+ endResetModel();
+ }
+
+ //todo process errors
+}
+
QHash ContainersModel::roleNames() const {
QHash roles;
roles[NameRole] = "name";
diff --git a/client/ui/models/containers_model.h b/client/ui/models/containers_model.h
index 36b5567a..642b6680 100644
--- a/client/ui/models/containers_model.h
+++ b/client/ui/models/containers_model.h
@@ -48,6 +48,8 @@ public slots:
void setCurrentlyInstalledContainerIndex(int index);
int getCurrentlyInstalledContainerIndex();
+ void removeAllContainers();
+
protected:
QHash roleNames() const override;
diff --git a/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml b/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml
index 20029eb0..2e6b3f2e 100644
--- a/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml
+++ b/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml
@@ -37,12 +37,11 @@ Drawer {
anchors.left: parent.left
anchors.right: parent.right
- anchors.rightMargin: 16
- anchors.leftMargin: 16
-
Header2TextType {
Layout.fillWidth: true
Layout.topMargin: 24
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
Layout.alignment: Qt.AlignHCenter
text: "Данные для подключения"
@@ -52,7 +51,7 @@ Drawer {
LabelWithButtonType {
id: ip
Layout.fillWidth: true
- Layout.topMargin: 32
+ Layout.topMargin: 16
text: "IP, логин и пароль от сервера"
buttonImage: "qrc:/images/controls/chevron-right.svg"
@@ -62,11 +61,9 @@ Drawer {
root.visible = false
}
}
- Rectangle {
- Layout.fillWidth: true
- height: 1
- color: "#2C2D30"
- }
+
+ DividerType {}
+
LabelWithButtonType {
Layout.fillWidth: true
@@ -78,10 +75,7 @@ Drawer {
root.visible = false
}
}
- Rectangle {
- Layout.fillWidth: true
- height: 1
- color: "#2C2D30"
- }
+
+ DividerType {}
}
}
diff --git a/client/ui/qml/Components/ContainersPageHomeListView.qml b/client/ui/qml/Components/ContainersPageHomeListView.qml
index 309b4217..f8b5101e 100644
--- a/client/ui/qml/Components/ContainersPageHomeListView.qml
+++ b/client/ui/qml/Components/ContainersPageHomeListView.qml
@@ -116,4 +116,3 @@ ListView {
}
}
}
-
diff --git a/client/ui/qml/Components/PageSettingsContainersListView.qml b/client/ui/qml/Components/PageSettingsContainersListView.qml
new file mode 100644
index 00000000..2a59b8b2
--- /dev/null
+++ b/client/ui/qml/Components/PageSettingsContainersListView.qml
@@ -0,0 +1,107 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import SortFilterProxyModel 0.2
+
+import PageEnum 1.0
+import ProtocolEnum 1.0
+
+import "../Controls2"
+import "../Controls2/TextTypes"
+
+
+ListView {
+ id: root
+
+ height: root.contentItem.height
+
+ clip: true
+
+ ButtonGroup {
+ id: containersRadioButtonGroup
+ }
+
+ delegate: Item {
+ implicitWidth: parent.width
+ implicitHeight: containerRadioButton.implicitHeight
+
+ RadioButton {
+ id: containerRadioButton
+
+ implicitWidth: parent.width
+ implicitHeight: containerRadioButtonContent.implicitHeight
+
+ hoverEnabled: true
+
+ ButtonGroup.group: containersRadioButtonGroup
+
+ checked: isDefault
+
+ indicator: Rectangle {
+ anchors.fill: parent
+ color: containerRadioButton.hovered ? Qt.rgba(1, 1, 1, 0.08) : "transparent"
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+
+ checkable: isInstalled
+
+ RowLayout {
+ id: containerRadioButtonContent
+ anchors.fill: parent
+
+ anchors.rightMargin: 16
+ anchors.leftMargin: 16
+
+ z: 1
+
+ ColumnLayout {
+ Layout.topMargin: 20
+ Layout.bottomMargin: 20
+
+ ListItemTitleType {
+ Layout.fillWidth: true
+
+ text: name
+ }
+
+ CaptionTextType {
+ Layout.fillWidth: true
+
+ text: description
+ color: "#878B91"
+ }
+ }
+
+ Image {
+ source: isInstalled ? "qrc:/images/controls/chevron-right.svg" : "qrc:/images/controls/download.svg"
+
+ width: 24
+ height: 24
+
+ Layout.rightMargin: 8
+ }
+ }
+
+ onClicked: {
+ if (isInstalled) {
+// isDefault = true
+// root.currentIndex = index
+ } else {
+ ContainersModel.setCurrentlyInstalledContainerIndex(root.model.mapToSource(index))
+ InstallController.setShouldCreateServer(false)
+ goToPage(PageEnum.PageSetupWizardProtocolSettings)
+ }
+ }
+
+ MouseArea {
+ anchors.fill: containerRadioButton
+ cursorShape: Qt.PointingHandCursor
+ enabled: false
+ }
+ }
+ }
+}
diff --git a/client/ui/qml/Controls2/DividerType.qml b/client/ui/qml/Controls2/DividerType.qml
new file mode 100644
index 00000000..6341807a
--- /dev/null
+++ b/client/ui/qml/Controls2/DividerType.qml
@@ -0,0 +1,8 @@
+import QtQuick
+import QtQuick.Layouts
+
+Rectangle {
+ Layout.fillWidth: true
+ height: 1
+ color: "#2C2D30"
+}
diff --git a/client/ui/qml/Controls2/LabelWithButtonType.qml b/client/ui/qml/Controls2/LabelWithButtonType.qml
index 2530f583..e4e711a6 100644
--- a/client/ui/qml/Controls2/LabelWithButtonType.qml
+++ b/client/ui/qml/Controls2/LabelWithButtonType.qml
@@ -2,6 +2,8 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
+import "TextTypes"
+
Item {
id: root
@@ -13,12 +15,16 @@ Item {
property alias buttonImage: button.image
property string iconImage
+ property string textColor: "#d7d8db"
+
implicitWidth: content.implicitWidth
implicitHeight: content.implicitHeight
RowLayout {
id: content
anchors.fill: parent
+ anchors.leftMargin: 16
+ anchors.rightMargin: 16
Image {
id: icon
@@ -28,34 +34,28 @@ Item {
}
ColumnLayout {
- Text {
- font.family: "PT Root UI VF"
- font.styleName: "normal"
- font.pixelSize: 18
- color: "#d7d8db"
+ ListItemTitleType {
text: root.text
- wrapMode: Text.WordWrap
+ color: textColor
Layout.fillWidth: true
- height: 22
+ Layout.topMargin: 16
+ Layout.bottomMargin: description.visible ? 0 : 16
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
- Text {
- font.family: "PT Root UI VF"
- font.styleName: "normal"
- font.pixelSize: 13
- font.letterSpacing: 0.02
+ CaptionTextType {
+ id: description
+
color: "#878B91"
text: root.descriptionText
- wrapMode: Text.WordWrap
visible: root.descriptionText !== ""
Layout.fillWidth: true
- height: 16
+ Layout.bottomMargin: 16
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
@@ -88,21 +88,45 @@ Item {
}
}
}
+
+ Rectangle {
+ id: background
+ anchors.fill: root
+ color: "transparent"
+
+
+ Behavior on color {
+ PropertyAnimation { duration: 200 }
+ }
+ }
+
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: {
- imageBackground.color = button.hoveredColor
+ if (buttonImage) {
+ imageBackground.color = button.hoveredColor
+ } else {
+ background.color = button.hoveredColor
+ }
}
onExited: {
- imageBackground.color = button.defaultColor
+ if (buttonImage) {
+ imageBackground.color = button.defaultColor
+ } else {
+ background.color = button.defaultColor
+ }
}
onPressedChanged: {
- imageBackground.color = pressed ? button.pressedColor : entered ? button.hoveredColor : button.defaultColor
+ if (buttonImage) {
+ imageBackground.color = pressed ? button.pressedColor : entered ? button.hoveredColor : button.defaultColor
+ } else {
+ background.color = pressed ? button.pressedColor : entered ? button.hoveredColor : button.defaultColor
+ }
}
onClicked: {
diff --git a/client/ui/qml/Controls2/TextTypes/ListItemTitleType.qml b/client/ui/qml/Controls2/TextTypes/ListItemTitleType.qml
new file mode 100644
index 00000000..23069db2
--- /dev/null
+++ b/client/ui/qml/Controls2/TextTypes/ListItemTitleType.qml
@@ -0,0 +1,12 @@
+import QtQuick
+
+Text {
+ height: 21.6
+
+ color: "#D7D8DB"
+ font.pixelSize: 18
+ font.weight: Font.Normal
+ font.family: "PT Root UI VF"
+
+ wrapMode: Text.WordWrap
+}
diff --git a/client/ui/qml/Pages2/PageHome.qml b/client/ui/qml/Pages2/PageHome.qml
index d5455849..1fba3bff 100644
--- a/client/ui/qml/Pages2/PageHome.qml
+++ b/client/ui/qml/Pages2/PageHome.qml
@@ -37,21 +37,6 @@ PageType {
}
}
- Connections {
- target: InstallController
-
- function onInstallContainerFinished() {
- goToStartPage()
- menu.visible = true
- containersDropDown.menuVisible = true
- }
-
- function onInstallServerFinished() {
- goToStartPage()
- menu.visible = true
- }
- }
-
Rectangle {
id: buttonBackground
anchors.fill: buttonContent
@@ -166,6 +151,10 @@ PageType {
ValueFilter {
roleName: "serviceType"
value: ProtocolEnum.Vpn
+ },
+ ValueFilter {
+ roleName: "isSupported"
+ value: true
}
]
}
diff --git a/client/ui/qml/Pages2/PageSettings.qml b/client/ui/qml/Pages2/PageSettings.qml
index 9d5b7442..57c252b4 100644
--- a/client/ui/qml/Pages2/PageSettings.qml
+++ b/client/ui/qml/Pages2/PageSettings.qml
@@ -5,6 +5,7 @@ import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
+import ProtocolEnum 1.0
import ContainerProps 1.0
import ProtocolProps 1.0
@@ -12,6 +13,7 @@ import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
+import "../Components"
PageType {
id: root
@@ -27,35 +29,28 @@ PageType {
]
}
- FlickableType {
- id: fl
- anchors.fill: parent
- contentHeight: content.height
-
ColumnLayout {
id: content
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
+ anchors.fill: parent
spacing: 16
Repeater {
+ id: header
model: proxyServersModel
delegate: HeaderType {
- id: header
-
Layout.fillWidth: true
Layout.topMargin: 20
Layout.leftMargin: 16
Layout.rightMargin: 16
- actionButtonImage: "qrc:/images/controls/plus.svg"
+ actionButtonImage: "qrc:/images/controls/edit-3.svg"
backButtonImage: "qrc:/images/controls/arrow-left.svg"
headerText: name
+ descriptionText: hostName
actionButtonFunction: function() {
connectionTypeSelection.visible = true
@@ -66,6 +61,82 @@ PageType {
}
}
}
+
+ TabBar {
+ id: tabBar
+
+ Layout.fillWidth: true
+
+ background: Rectangle {
+ color: "transparent"
+ }
+
+ TabButtonType {
+ isSelected: tabBar.currentIndex === 0
+ text: qsTr("Protocols")
+ }
+ TabButtonType {
+ isSelected: tabBar.currentIndex === 1
+ text: qsTr("Services")
+ }
+ TabButtonType {
+ isSelected: tabBar.currentIndex === 2
+ text: qsTr("Data")
+ }
+ }
+
+ StackLayout {
+ id: stackLayout
+ currentIndex: tabBar.currentIndex
+
+ Layout.fillWidth: true
+ height: root.height
+
+ StackView {
+ id: protocolsStackView
+ initialItem: PageSettingsContainersListView {
+ model: SortFilterProxyModel {
+ sourceModel: ContainersModel
+ filters: [
+ ValueFilter {
+ roleName: "serviceType"
+ value: ProtocolEnum.Vpn
+ },
+ ValueFilter {
+ roleName: "isSupported"
+ value: true
+ }
+ ]
+ }
+ }
+ }
+
+ StackView {
+ id: servicesStackView
+ initialItem: PageSettingsContainersListView {
+ model: SortFilterProxyModel {
+ sourceModel: ContainersModel
+ filters: [
+ ValueFilter {
+ roleName: "serviceType"
+ value: ProtocolEnum.Other
+ },
+ ValueFilter {
+ roleName: "isSupported"
+ value: true
+ }
+ ]
+ }
+ }
+ }
+
+ StackView {
+ id: dataStackView
+ initialItem: PageSettingsData {
+
+ }
+ }
+ }
}
- }
+// }
}
diff --git a/client/ui/qml/Pages2/PageSettingsData.qml b/client/ui/qml/Pages2/PageSettingsData.qml
new file mode 100644
index 00000000..74293aa5
--- /dev/null
+++ b/client/ui/qml/Pages2/PageSettingsData.qml
@@ -0,0 +1,67 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import SortFilterProxyModel 0.2
+
+import PageEnum 1.0
+import ProtocolEnum 1.0
+
+import "../Controls2"
+import "../Controls2/TextTypes"
+
+PageType {
+ id: root
+
+ FlickableType {
+ id: fl
+ anchors.top: root.top
+ anchors.bottom: root.bottom
+ contentHeight: content.height
+
+ ColumnLayout {
+ id: content
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+
+ text: "Clear Amnezia cache"
+ descriptionText: "May be needed when changing other settings"
+
+ clickedFunction: function() {
+ }
+ }
+
+ DividerType {}
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+
+ text: "Remove server from application"
+ textColor: "#EB5757"
+
+ clickedFunction: function() {
+ }
+ }
+
+ DividerType {}
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+
+ text: "Clear server from Amnezia software"
+ textColor: "#EB5757"
+
+ clickedFunction: function() {
+ ContainersModel.removeAllContainers()
+ }
+ }
+
+ DividerType {}
+ }
+ }
+}
diff --git a/client/ui/qml/Pages2/PageSettingsServersList.qml b/client/ui/qml/Pages2/PageSettingsServersList.qml
index 79e24f75..2344b7e8 100644
--- a/client/ui/qml/Pages2/PageSettingsServersList.qml
+++ b/client/ui/qml/Pages2/PageSettingsServersList.qml
@@ -57,11 +57,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
- anchors.leftMargin: 16
- anchors.rightMargin: 16
-
- spacing: 16
-
ListView {
id: servers
width: parent.width
@@ -85,8 +80,6 @@ PageType {
LabelWithButtonType {
id: server
Layout.fillWidth: true
- Layout.topMargin: 16
- Layout.bottomMargin: 16
text: name
descriptionText: hostName
@@ -98,11 +91,7 @@ PageType {
}
}
- Rectangle {
- Layout.fillWidth: true
- height: 1
- color: "#2C2D30"
- }
+ DividerType {}
}
}
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
index 53a40889..25b88f76 100644
--- a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
@@ -33,14 +33,12 @@ PageType {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
- anchors.rightMargin: 16
- anchors.leftMargin: 16
-
- spacing: 16
HeaderType {
Layout.fillWidth: true
Layout.topMargin: 20
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
backButtonImage: "qrc:/images/controls/arrow-left.svg"
@@ -52,6 +50,8 @@ PageType {
Header2TextType {
Layout.fillWidth: true
Layout.topMargin: 32
+ Layout.rightMargin: 16
+ Layout.leftMargin: 16
text: "Что у вас есть?"
}
@@ -75,11 +75,8 @@ PageType {
}
}
}
- Rectangle {
- Layout.fillWidth: true
- height: 1
- color: "#2C2D30"
- }
+
+ DividerType {}
//todo ifdef mobile platforms
LabelWithButtonType {
@@ -93,11 +90,7 @@ PageType {
}
}
- Rectangle {
- Layout.fillWidth: true
- height: 1
- color: "#2C2D30"
- }
+ DividerType {}
LabelWithButtonType {
Layout.fillWidth: true
@@ -111,11 +104,7 @@ PageType {
}
}
- Rectangle {
- Layout.fillWidth: true
- height: 1
- color: "#2C2D30"
- }
+ DividerType {}
}
}
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml
index fd8aac6b..006743d9 100644
--- a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml
@@ -23,6 +23,14 @@ PageType {
closePage()
PageController.showErrorMessage(errorMessage)
}
+
+ function onInstallContainerFinished() {
+ goToStartPage()
+ }
+
+ function onInstallServerFinished() {
+ goToStartPage()
+ }
}
SortFilterProxyModel {
diff --git a/client/ui/qml/Pages2/PageSetupWizardProtocols.qml b/client/ui/qml/Pages2/PageSetupWizardProtocols.qml
index bffe09cb..cdacaf04 100644
--- a/client/ui/qml/Pages2/PageSetupWizardProtocols.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardProtocols.qml
@@ -75,12 +75,12 @@ PageType {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
+ anchors.rightMargin: -16
+ anchors.leftMargin: -16
LabelWithButtonType {
id: container
Layout.fillWidth: true
- Layout.topMargin: 16
- Layout.bottomMargin: 16
text: name
descriptionText: description
@@ -92,11 +92,7 @@ PageType {
}
}
- Rectangle {
- Layout.fillWidth: true
- height: 1
- color: "#2C2D30"
- }
+ DividerType {}
}
}
}
diff --git a/client/ui/qml/Pages2/PageSetupWizardStart.qml b/client/ui/qml/Pages2/PageSetupWizardStart.qml
index 4d0f4c5c..804e145c 100644
--- a/client/ui/qml/Pages2/PageSetupWizardStart.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardStart.qml
@@ -26,8 +26,9 @@ PageType {
target: InstallController
function onInstallServerFinished() {
+ //todo add smt like changeStartPage
goToStartPage()
-// goToPage(PageEnum.PageStart)
+ goToPage(PageEnum.PageStart)
}
}
diff --git a/client/ui/qml/Pages2/PageStart.qml b/client/ui/qml/Pages2/PageStart.qml
index 19ea3bc4..c50d4591 100644
--- a/client/ui/qml/Pages2/PageStart.qml
+++ b/client/ui/qml/Pages2/PageStart.qml
@@ -38,8 +38,9 @@ PageType {
height: root.height - tabBar.implicitHeight
StackView {
- id: homeStackView
- initialItem: "PageHome.qml" //PageController.getPagePath(PageEnum.PageSettingsServersList)
+ initialItem: PageHome {
+ id: pageHome
+ }
}
Item {
@@ -47,8 +48,9 @@ PageType {
}
StackView {
- id: settingsStackView
- initialItem: "PageSettingsServersList.qml" //PageController.getPagePath(PageEnum.PageSettingsServersList)
+ initialItem: PageSettingsServersList {
+ id: pageSettingsServersList
+ }
}
}
@@ -72,6 +74,9 @@ PageType {
TabImageButtonType {
isSelected: tabBar.currentIndex === 0
image: "qrc:/images/controls/home.svg"
+ onClicked: {
+ pageSettingsServersList.goToStartPage()
+ }
}
TabImageButtonType {
isSelected: tabBar.currentIndex === 1
@@ -80,6 +85,9 @@ PageType {
TabImageButtonType {
isSelected: tabBar.currentIndex === 2
image: "qrc:/images/controls/settings-2.svg"
+ onClicked: {
+ pageHome.goToStartPage()
+ }
}
}