From b66f4bf2bee3a31fe1cbb7036a33893127a90686 Mon Sep 17 00:00:00 2001 From: Vladimir Kuznetsov Date: Thu, 11 May 2023 14:50:50 +0800 Subject: [PATCH] added display of protocols on PageHome --- client/amnezia_application.cpp | 1 - client/images/controls/plus.svg | 4 + client/resources.qrc | 1 + client/ui/models/servers_model.cpp | 50 ++++--- client/ui/models/servers_model.h | 5 +- client/ui/pages_logic/ServerListLogic.cpp | 2 +- client/ui/qml/Controls2/BasicButtonType.qml | 2 +- client/ui/qml/Controls2/DropDownType.qml | 80 +++-------- client/ui/qml/Controls2/Header2Type.qml | 38 +++++- client/ui/qml/Controls2/HeaderType.qml | 42 +++++- .../ui/qml/Controls2/LabelWithButtonType.qml | 4 +- client/ui/qml/Controls2/TabButtonType.qml | 2 +- .../ui/qml/Controls2/VerticalRadioButton.qml | 2 +- client/ui/qml/Pages2/PageHome.qml | 126 +++++++++++++++--- .../Pages2/PageSetupWizardConfigSource.qml | 2 +- .../qml/Pages2/PageSetupWizardCredentials.qml | 2 +- client/ui/qml/Pages2/PageSetupWizardEasy.qml | 2 +- .../qml/Pages2/PageSetupWizardInstalling.qml | 2 +- .../PageSetupWizardProtocolSettings.qml | 2 +- .../qml/Pages2/PageSetupWizardProtocols.qml | 2 +- .../ui/qml/Pages2/PageSetupWizardTextKey.qml | 2 +- client/ui/qml/Pages2/PageTest.qml | 2 +- 22 files changed, 237 insertions(+), 138 deletions(-) create mode 100644 client/images/controls/plus.svg diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 2cd616795..dea868e44 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -187,7 +187,6 @@ void AmneziaApplication::loadFonts() QFontDatabase::addApplicationFont(":/fonts/Lato-Regular.ttf"); QFontDatabase::addApplicationFont(":/fonts/Lato-Thin.ttf"); QFontDatabase::addApplicationFont(":/fonts/Lato-ThinItalic.ttf"); - QFontDatabase::addApplicationFont(":/fonts/pt-root-ui_vf.ttf"); } diff --git a/client/images/controls/plus.svg b/client/images/controls/plus.svg new file mode 100644 index 000000000..96d0b71d5 --- /dev/null +++ b/client/images/controls/plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/client/resources.qrc b/client/resources.qrc index f5817eb0e..307c992de 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -221,5 +221,6 @@ ui/qml/Controls2/TextTypes/LabelTextType.qml ui/qml/Controls2/TextTypes/ButtonTextType.qml ui/qml/Controls2/Header2Type.qml + images/controls/plus.svg diff --git a/client/ui/models/servers_model.cpp b/client/ui/models/servers_model.cpp index 94d3ced43..89287b7f1 100644 --- a/client/ui/models/servers_model.cpp +++ b/client/ui/models/servers_model.cpp @@ -2,41 +2,34 @@ ServersModel::ServersModel(std::shared_ptr settings, QObject *parent) : m_settings(settings), QAbstractListModel(parent) { + refresh(); +} + +void ServersModel::refresh() +{ + beginResetModel(); const QJsonArray &servers = m_settings->serversArray(); int defaultServer = m_settings->defaultServerIndex(); QVector serverListContent; for(int i = 0; i < servers.size(); i++) { - ServerModelContent c; + ServerModelContent content; auto server = servers.at(i).toObject(); - c.desc = server.value(config_key::description).toString(); - c.address = server.value(config_key::hostName).toString(); - if (c.desc.isEmpty()) { - c.desc = c.address; + content.desc = server.value(config_key::description).toString(); + content.address = server.value(config_key::hostName).toString(); + if (content.desc.isEmpty()) { + content.desc = content.address; } - c.isDefault = (i == defaultServer); - serverListContent.push_back(c); + content.isDefault = (i == defaultServer); + serverListContent.push_back(content); } - setContent(serverListContent); -} - -void ServersModel::clearData() -{ - beginResetModel(); - m_content.clear(); - endResetModel(); -} - -void ServersModel::setContent(const QVector &data) -{ - beginResetModel(); - m_content = data; + m_data = serverListContent; endResetModel(); } int ServersModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return static_cast(m_content.size()); + return static_cast(m_data.size()); } QHash ServersModel::roleNames() const { @@ -50,19 +43,24 @@ QHash ServersModel::roleNames() const { QVariant ServersModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() < 0 - || index.row() >= static_cast(m_content.size())) { + || index.row() >= static_cast(m_data.size())) { return QVariant(); } if (role == DescRole) { - return m_content[index.row()].desc; + return m_data[index.row()].desc; } if (role == AddressRole) { - return m_content[index.row()].address; + return m_data[index.row()].address; } if (role == IsDefaultRole) { - return m_content[index.row()].isDefault; + return m_data[index.row()].isDefault; } return QVariant(); } +void ServersModel::setDefaultServerIndex(int index) +{ + +} + diff --git a/client/ui/models/servers_model.h b/client/ui/models/servers_model.h index e60aea6b8..c8c32b56d 100644 --- a/client/ui/models/servers_model.h +++ b/client/ui/models/servers_model.h @@ -23,8 +23,7 @@ class ServersModel : public QAbstractListModel IsDefaultRole }; - void clearData(); - void setContent(const QVector& data); + void refresh(); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; @@ -33,7 +32,7 @@ class ServersModel : public QAbstractListModel QHash roleNames() const override; private: - QVector m_content; + QVector m_data; std::shared_ptr m_settings; }; diff --git a/client/ui/pages_logic/ServerListLogic.cpp b/client/ui/pages_logic/ServerListLogic.cpp index 4a17e2022..56a682b85 100644 --- a/client/ui/pages_logic/ServerListLogic.cpp +++ b/client/ui/pages_logic/ServerListLogic.cpp @@ -45,5 +45,5 @@ void ServerListLogic::onUpdatePage() c.isDefault = (i == defaultServer); serverListContent.push_back(c); } - qobject_cast(m_serverListModel)->setContent(serverListContent); +// qobject_cast(m_serverListModel)->setContent(serverListContent); } diff --git a/client/ui/qml/Controls2/BasicButtonType.qml b/client/ui/qml/Controls2/BasicButtonType.qml index da5d2abfe..266beefe1 100644 --- a/client/ui/qml/Controls2/BasicButtonType.qml +++ b/client/ui/qml/Controls2/BasicButtonType.qml @@ -48,7 +48,7 @@ Button { contentItem: Text { anchors.fill: background - font.family: "PT Root UI" + font.family: "PT Root UI VF" font.styleName: "normal" font.weight: 400 font.pixelSize: 16 diff --git a/client/ui/qml/Controls2/DropDownType.qml b/client/ui/qml/Controls2/DropDownType.qml index 6f5111948..ea6ca5fca 100644 --- a/client/ui/qml/Controls2/DropDownType.qml +++ b/client/ui/qml/Controls2/DropDownType.qml @@ -10,6 +10,9 @@ Item { property string text property string descriptionText + property string headerText + property string headerBackButtonImage + property var onClickedFunc property string buttonImage: "qrc:/images/controls/chevron-down.svg" property string buttonImageColor: "#494B50" @@ -22,7 +25,10 @@ Item { property string borderColor: "#494B50" property int borderWidth: 1 - property alias menuModel: menuContent.model + property Component menuDelegate + property variant menuModel + + property alias menuVisible: menu.visible implicitWidth: buttonContent.implicitWidth implicitHeight: buttonContent.implicitHeight @@ -128,12 +134,13 @@ Item { color: Qt.rgba(14/255, 14/255, 17/255, 0.8) } - Header2TextType { + Header2Type { id: header - width: parent.width - text: "Данные для подключения" - wrapMode: Text.WordWrap + headerText: root.headerText + backButtonImage: root.headerBackButtonImage + + width: parent.width anchors.top: parent.top anchors.left: parent.left @@ -170,64 +177,13 @@ Item { clip: true interactive: false - delegate: Item { - implicitWidth: menuContent.width - implicitHeight: radioButton.implicitHeight - - RadioButton { - id: radioButton - - implicitWidth: parent.width - implicitHeight: radioButtonContent.implicitHeight - - hoverEnabled: true - - ButtonGroup.group: radioButtonGroup - - indicator: Rectangle { - anchors.fill: parent - color: radioButton.hovered ? "#2C2D30" : "#1C1D21" - } - - RowLayout { - id: radioButtonContent - anchors.fill: parent - - anchors.rightMargin: 16 - anchors.leftMargin: 16 - - z: 1 - - Text { - id: text - - text: modelData - color: "#D7D8DB" - font.pixelSize: 16 - font.weight: 400 - font.family: "PT Root UI VF" - - height: 24 - - Layout.fillWidth: true - Layout.topMargin: 20 - Layout.bottomMargin: 20 - } - - Image { - source: "qrc:/images/controls/check.svg" - visible: radioButton.checked - width: 24 - height: 24 - - Layout.rightMargin: 8 - } - } + model: root.menuModel - onClicked: { - root.text = modelData - menu.visible = false - } + delegate: Row { + Loader { + id: loader + sourceComponent: root.menuDelegate + property QtObject modelData: model } } } diff --git a/client/ui/qml/Controls2/Header2Type.qml b/client/ui/qml/Controls2/Header2Type.qml index e0173a73b..5c2f0c9ba 100644 --- a/client/ui/qml/Controls2/Header2Type.qml +++ b/client/ui/qml/Controls2/Header2Type.qml @@ -6,7 +6,12 @@ import "TextTypes" Item { id: root - property string buttonImage + property string backButtonImage + property string actionButtonImage + + property var backButtonFunction + property var actionButtonFunction + property string headerText property string descriptionText @@ -22,22 +27,41 @@ Item { Layout.leftMargin: -6 - image: root.buttonImage + image: root.backButtonImage imageColor: "#D7D8DB" visible: image ? true : false onClicked: { - UiLogic.closePage() + if (backButtonFunction && typeof backButtonFunction === "function") { + backButtonFunction() + } } } - Header2TextType { - id: header + RowLayout { + Header2TextType { + id: header - Layout.fillWidth: true + Layout.fillWidth: true + + text: root.headerText + } - text: root.headerText + ImageButtonType { + id: headerActionButton + + image: root.actionButtonImage + imageColor: "#D7D8DB" + + visible: image ? true : false + + onClicked: { + if (actionButtonImage && typeof actionButtonImage === "function") { + actionButtonImage() + } + } + } } ParagraphTextType { diff --git a/client/ui/qml/Controls2/HeaderType.qml b/client/ui/qml/Controls2/HeaderType.qml index 407f67f0f..a051d2d87 100644 --- a/client/ui/qml/Controls2/HeaderType.qml +++ b/client/ui/qml/Controls2/HeaderType.qml @@ -6,7 +6,12 @@ import "TextTypes" Item { id: root - property string buttonImage + property string backButtonImage + property string actionButtonImage + + property var backButtonFunction + property var actionButtonFunction + property string headerText property string descriptionText @@ -22,22 +27,43 @@ Item { Layout.leftMargin: -6 - image: root.buttonImage + image: root.backButtonImage imageColor: "#D7D8DB" visible: image ? true : false onClicked: { - UiLogic.closePage() + if (backButtonFunction && typeof backButtonFunction === "function") { + backButtonFunction() + } } } - Header1TextType { - id: header + RowLayout { + Header1TextType { + id: header - Layout.fillWidth: true + Layout.fillWidth: true + + text: root.headerText + } + + ImageButtonType { + id: headerActionButton - text: root.headerText + Layout.alignment: Qt.AlignRight + + image: root.actionButtonImage + imageColor: "#D7D8DB" + + visible: image ? true : false + + onClicked: { + if (actionButtonImage && typeof actionButtonImage === "function") { + actionButtonImage() + } + } + } } ParagraphTextType { @@ -49,6 +75,8 @@ Item { text: root.descriptionText color: "#878B91" + + visible: root.descriptionText !== "" } } } diff --git a/client/ui/qml/Controls2/LabelWithButtonType.qml b/client/ui/qml/Controls2/LabelWithButtonType.qml index b6d113bb2..d8e195f1d 100644 --- a/client/ui/qml/Controls2/LabelWithButtonType.qml +++ b/client/ui/qml/Controls2/LabelWithButtonType.qml @@ -29,7 +29,7 @@ Item { ColumnLayout { Text { - font.family: "PT Root UI" + font.family: "PT Root UI VF" font.styleName: "normal" font.pixelSize: 18 color: "#d7d8db" @@ -44,7 +44,7 @@ Item { } Text { - font.family: "PT Root UI" + font.family: "PT Root UI VF" font.styleName: "normal" font.pixelSize: 13 font.letterSpacing: 0.02 diff --git a/client/ui/qml/Controls2/TabButtonType.qml b/client/ui/qml/Controls2/TabButtonType.qml index f39edefd2..4699dfcd2 100644 --- a/client/ui/qml/Controls2/TabButtonType.qml +++ b/client/ui/qml/Controls2/TabButtonType.qml @@ -43,7 +43,7 @@ TabButton { anchors.fill: background height: 24 - font.family: "PT Root UI" + font.family: "PT Root UI VF" font.styleName: "normal" font.weight: 500 font.pixelSize: 16 diff --git a/client/ui/qml/Controls2/VerticalRadioButton.qml b/client/ui/qml/Controls2/VerticalRadioButton.qml index edcd1c29e..420051cd5 100644 --- a/client/ui/qml/Controls2/VerticalRadioButton.qml +++ b/client/ui/qml/Controls2/VerticalRadioButton.qml @@ -136,7 +136,7 @@ RadioButton { } Text { - font.family: "PT Root UI" + font.family: "PT Root UI VF" font.styleName: "normal" font.pixelSize: 13 font.letterSpacing: 0.02 diff --git a/client/ui/qml/Pages2/PageHome.qml b/client/ui/qml/Pages2/PageHome.qml index ad1b7d38c..3f81f1681 100644 --- a/client/ui/qml/Pages2/PageHome.qml +++ b/client/ui/qml/Pages2/PageHome.qml @@ -2,7 +2,10 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import SortFilterProxyModel 0.2 + import PageEnum 1.0 +import ProtocolEnum 1.0 import "./" import "../Pages" @@ -125,11 +128,27 @@ PageBase { } RowLayout { - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter spacing: 8 + SortFilterProxyModel { + id: proxyContainersModel + sourceModel: ContainersModel + filters: [ + ValueFilter { + roleName: "service_type_role" + value: ProtocolEnum.Vpn + }, + ValueFilter { + roleName: "is_installed_role" + value: true + } + ] + } + DropDownType { + id: protocolsDropDown + implicitHeight: 40 borderWidth: 0 @@ -138,7 +157,83 @@ PageBase { defaultColor: "#D7D8DB" textColor: "#0E0E11" - text: "testtesttest" + headerText: "Протокол подключения" + headerBackButtonImage: "qrc:/images/controls/arrow-left.svg" + + menuModel: proxyContainersModel + + menuDelegate: Item { + implicitWidth: menuContent.width + implicitHeight: radioButton.implicitHeight + + RadioButton { + id: radioButton + + implicitWidth: parent.width + implicitHeight: radioButtonContent.implicitHeight + + hoverEnabled: true + + ButtonGroup.group: radioButtonGroup + + indicator: Rectangle { + anchors.fill: parent + color: radioButton.hovered ? "#2C2D30" : "#1C1D21" + } + + RowLayout { + id: radioButtonContent + anchors.fill: parent + + anchors.rightMargin: 16 + anchors.leftMargin: 16 + + z: 1 + + Text { + id: text + + // todo remove dirty hack? + text: { + if (modelData !== null) { + return modelData.name_role + } else + return "" + } + color: "#D7D8DB" + font.pixelSize: 16 + font.weight: 400 + font.family: "PT Root UI VF" + + height: 24 + + Layout.fillWidth: true + Layout.topMargin: 20 + Layout.bottomMargin: 20 + } + + Image { + source: "qrc:/images/controls/check.svg" + visible: radioButton.checked + width: 24 + height: 24 + + Layout.rightMargin: 8 + } + } + + onClicked: { + protocolsDropDown.text = text.text + protocolsDropDown.menuVisible = false + } + } + + Component.onCompleted: { + if (modelData !== null && modelData.default_role) { + protocolsDropDown.text = modelData.name_role + } + } + } } BasicButtonType { @@ -149,29 +244,17 @@ PageBase { } Header2Type { + Layout.fillWidth: true + Layout.topMargin: 48 Layout.leftMargin: 16 Layout.rightMargin: 16 + actionButtonImage: "qrc:/images/controls/plus.svg" + headerText: "Серверы" } } - -// Header2TextType { -// id: menuHeader -// width: parent.width - -// text: "Данные для подключения" -// wrapMode: Text.WordWrap - -// anchors.top: parent.top -// anchors.left: parent.left -// anchors.right: parent.right -// anchors.topMargin: 16 -// anchors.leftMargin: 16 -// anchors.rightMargin: 16 -// } - FlickableType { anchors.top: menuHeader.bottom anchors.topMargin: 16 @@ -257,6 +340,13 @@ PageBase { Layout.rightMargin: 8 } } + + onClicked: { + console.log(index) + ContainersModel.setSelectedServerIndex(index) + root.currentServerName = desc + root.currentServerDescription = address + } } } } diff --git a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml index a6ba52bb8..5445d1f34 100644 --- a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml +++ b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml @@ -36,7 +36,7 @@ PageBase { Layout.fillWidth: true Layout.topMargin: 20 - buttonImage: "qrc:/images/controls/arrow-left.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" headerText: "Подключение к серверу" descriptionText: "Не используйте код подключения из публичных источников. Его могли создать, чтобы перехватывать ваши данные.\n diff --git a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml index a6e98fee6..506c1cde3 100644 --- a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml +++ b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml @@ -34,7 +34,7 @@ PageBase { Layout.fillWidth: true Layout.topMargin: 20 - buttonImage: "qrc:/images/controls/arrow-left.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" headerText: "Подключение к серверу" } diff --git a/client/ui/qml/Pages2/PageSetupWizardEasy.qml b/client/ui/qml/Pages2/PageSetupWizardEasy.qml index 8c75a1dfa..94e22fe3e 100644 --- a/client/ui/qml/Pages2/PageSetupWizardEasy.qml +++ b/client/ui/qml/Pages2/PageSetupWizardEasy.qml @@ -34,7 +34,7 @@ PageBase { Layout.fillWidth: true Layout.topMargin: 20 - buttonImage: "qrc:/images/controls/arrow-left.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" headerText: "Какой уровень контроля интернета в вашем регионе?" } diff --git a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml index 3445b5334..a74182578 100644 --- a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml +++ b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml @@ -36,7 +36,7 @@ PageBase { Layout.topMargin: 20 //TODO remove later - buttonImage: "qrc:/images/controls/arrow-left.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" headerText: "Установка" descriptionText: ContainersModel.getCurrentlyInstalledContainerName() diff --git a/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml b/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml index 17c22b04c..78856444a 100644 --- a/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml +++ b/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml @@ -35,7 +35,7 @@ PageBase { Layout.fillWidth: true Layout.topMargin: 20 - buttonImage: "qrc:/images/controls/arrow-left.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" headerText: "Установка " + ContainersModel.getCurrentlyInstalledContainerName() descriptionText: "Эти настройки можно будет изменить позже" diff --git a/client/ui/qml/Pages2/PageSetupWizardProtocols.qml b/client/ui/qml/Pages2/PageSetupWizardProtocols.qml index ad4efbc21..501076155 100644 --- a/client/ui/qml/Pages2/PageSetupWizardProtocols.qml +++ b/client/ui/qml/Pages2/PageSetupWizardProtocols.qml @@ -51,7 +51,7 @@ PageBase { HeaderType { width: parent.width - buttonImage: "qrc:/images/controls/arrow-left.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" headerText: "Протокол подключения" descriptionText: "Выберите более приоритетный для вас. Позже можно будет установить остальные протоколы и доп сервисы, вроде DNS-прокси и SFTP." diff --git a/client/ui/qml/Pages2/PageSetupWizardTextKey.qml b/client/ui/qml/Pages2/PageSetupWizardTextKey.qml index 9fddc573d..d295f1b97 100644 --- a/client/ui/qml/Pages2/PageSetupWizardTextKey.qml +++ b/client/ui/qml/Pages2/PageSetupWizardTextKey.qml @@ -35,7 +35,7 @@ PageBase { Layout.fillWidth: true Layout.topMargin: 20 - buttonImage: "qrc:/images/controls/arrow-left.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" headerText: "Ключ для подключения" descriptionText: "Строка, которая начинается с vpn://..." diff --git a/client/ui/qml/Pages2/PageTest.qml b/client/ui/qml/Pages2/PageTest.qml index af9ef2863..2336e46e8 100644 --- a/client/ui/qml/Pages2/PageTest.qml +++ b/client/ui/qml/Pages2/PageTest.qml @@ -29,7 +29,7 @@ PageBase { Layout.bottomMargin: 32 Layout.fillWidth: true - buttonImage: "qrc:/images/controls/arrow-left.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" headerText: "Server 1" descriptionText: "root 192.168.111.111" }