From de0cd976debb0691e69b77e1f0cc62b4e17d12de Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Thu, 1 Jun 2023 11:25:33 +0800 Subject: [PATCH] added page transition effects - added functionality for buttons on PageSettingsServerData page --- client/amnezia_application.cpp | 2 +- client/images/controls/amnezia.svg | 3 + client/images/controls/app.svg | 6 + client/images/controls/radio.svg | 7 + client/images/controls/save.svg | 5 + client/images/controls/server.svg | 6 + client/resources.qrc | 18 +- .../ui/controllers/connectionController.cpp | 1 - client/ui/controllers/installController.cpp | 5 +- client/ui/controllers/pageController.cpp | 3 +- client/ui/controllers/pageController.h | 7 +- client/ui/models/containers_model.cpp | 11 +- client/ui/models/containers_model.h | 1 + client/ui/models/servers_model.cpp | 51 ++++-- client/ui/models/servers_model.h | 5 +- client/ui/pages.h | 9 +- client/ui/qml/Components/ConnectButton.qml | 14 +- .../ConnectionTypeSelectionDrawer.qml | 6 +- ...istView.qml => HomeContainersListView.qml} | 59 +----- ...iew.qml => SettingsContainersListView.qml} | 3 +- client/ui/qml/Controls2/DrawerType.qml | 20 +++ client/ui/qml/Controls2/DropDownType.qml | 6 +- client/ui/qml/Controls2/PageType.qml | 5 +- client/ui/qml/Controls2/StackViewType.qml | 61 +++++++ client/ui/qml/Controls2/SwitcherType.qml | 1 + .../ui/qml/Controls2/VerticalRadioButton.qml | 61 +++++-- client/ui/qml/Pages2/PageHome.qml | 121 ++++++------- client/ui/qml/Pages2/PageSettings.qml | 169 +++++++----------- ...ngsData.qml => PageSettingsServerData.qml} | 13 ++ .../ui/qml/Pages2/PageSettingsServerInfo.qml | 134 ++++++++++++++ .../Pages2/PageSettingsServerProtocols.qml | 38 ++++ .../qml/Pages2/PageSettingsServerServices.qml | 38 ++++ .../ui/qml/Pages2/PageSettingsServersList.qml | 7 +- .../qml/Pages2/PageSetupWizardInstalling.qml | 16 ++ client/ui/qml/Pages2/PageSetupWizardStart.qml | 10 -- client/ui/qml/Pages2/PageStart.qml | 31 ++-- client/ui/qml/main2.qml | 24 ++- client/ui/uilogic.cpp | 14 +- 38 files changed, 656 insertions(+), 335 deletions(-) create mode 100644 client/images/controls/amnezia.svg create mode 100644 client/images/controls/app.svg create mode 100644 client/images/controls/radio.svg create mode 100644 client/images/controls/save.svg create mode 100644 client/images/controls/server.svg rename client/ui/qml/Components/{ContainersPageHomeListView.qml => HomeContainersListView.qml} (52%) rename client/ui/qml/Components/{PageSettingsContainersListView.qml => SettingsContainersListView.qml} (97%) create mode 100644 client/ui/qml/Controls2/DrawerType.qml create mode 100644 client/ui/qml/Controls2/StackViewType.qml rename client/ui/qml/Pages2/{PageSettingsData.qml => PageSettingsServerData.qml} (67%) create mode 100644 client/ui/qml/Pages2/PageSettingsServerInfo.qml create mode 100644 client/ui/qml/Pages2/PageSettingsServerProtocols.qml create mode 100644 client/ui/qml/Pages2/PageSettingsServerServices.qml diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 9fdddc86..c8bdcf3b 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -179,7 +179,7 @@ void AmneziaApplication::registerTypes() qRegisterMetaType("PageProtocolLogicBase *"); - declareQmlPageEnum(); +// declareQmlPageEnum(); declareQmlProtocolEnum(); declareQmlContainerEnum(); diff --git a/client/images/controls/amnezia.svg b/client/images/controls/amnezia.svg new file mode 100644 index 00000000..0a6017dd --- /dev/null +++ b/client/images/controls/amnezia.svg @@ -0,0 +1,3 @@ + + + diff --git a/client/images/controls/app.svg b/client/images/controls/app.svg new file mode 100644 index 00000000..87775cd1 --- /dev/null +++ b/client/images/controls/app.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/client/images/controls/radio.svg b/client/images/controls/radio.svg new file mode 100644 index 00000000..27731814 --- /dev/null +++ b/client/images/controls/radio.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/client/images/controls/save.svg b/client/images/controls/save.svg new file mode 100644 index 00000000..442ff72c --- /dev/null +++ b/client/images/controls/save.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/client/images/controls/server.svg b/client/images/controls/server.svg new file mode 100644 index 00000000..52aad656 --- /dev/null +++ b/client/images/controls/server.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/client/resources.qrc b/client/resources.qrc index ca02df7d..db53165c 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -228,16 +228,26 @@ images/controls/download.svg ui/qml/Controls2/ProgressBarType.qml ui/qml/Components/ConnectionTypeSelectionDrawer.qml - ui/qml/Components/ContainersPageHomeListView.qml + ui/qml/Components/HomeContainersListView.qml ui/qml/Controls2/TextTypes/CaptionTextType.qml images/controls/settings.svg - ui/qml/Pages2/PageSettings.qml + ui/qml/Pages2/PageSettingsServerInfo.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/Pages2/PageSettingsServerData.qml + ui/qml/Components/SettingsContainersListView.qml ui/qml/Controls2/TextTypes/ListItemTitleType.qml ui/qml/Controls2/DividerType.qml + ui/qml/Controls2/DrawerType.qml + ui/qml/Controls2/StackViewType.qml + ui/qml/Pages2/PageSettings.qml + images/controls/amnezia.svg + images/controls/app.svg + images/controls/radio.svg + images/controls/save.svg + images/controls/server.svg + ui/qml/Pages2/PageSettingsServerProtocols.qml + ui/qml/Pages2/PageSettingsServerServices.qml diff --git a/client/ui/controllers/connectionController.cpp b/client/ui/controllers/connectionController.cpp index 58fef373..617fd5ee 100644 --- a/client/ui/controllers/connectionController.cpp +++ b/client/ui/controllers/connectionController.cpp @@ -74,4 +74,3 @@ bool ConnectionController::closeVpnConnection() emit disconnectFromVpn(); m_isConnected = false; } - diff --git a/client/ui/controllers/installController.cpp b/client/ui/controllers/installController.cpp index 31f58a2a..15a24c31 100644 --- a/client/ui/controllers/installController.cpp +++ b/client/ui/controllers/installController.cpp @@ -49,8 +49,9 @@ void InstallController::installServer(DockerContainer container, QJsonObject& co server.insert(config_key::containers, QJsonArray{ config }); server.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); - m_settings->addServer(server); - m_settings->setDefaultServer(m_settings->serversCount() - 1); + m_serversModel->addServer(server); + auto newServerIndex = m_serversModel->index(m_serversModel->getServersCount() - 1); + m_serversModel->setData(newServerIndex, true, ServersModel::ServersModelRoles::IsDefaultRole); emit installServerFinished(); return; diff --git a/client/ui/controllers/pageController.cpp b/client/ui/controllers/pageController.cpp index 63c3ba58..e49177a5 100644 --- a/client/ui/controllers/pageController.cpp +++ b/client/ui/controllers/pageController.cpp @@ -9,7 +9,8 @@ QString PageController::getInitialPage() { if (m_serversModel->getServersCount()) { if (m_serversModel->getDefaultServerIndex() < 0) { - m_serversModel->setDefaultServerIndex(0); + auto defaultServerIndex = m_serversModel->index(0); + m_serversModel->setData(defaultServerIndex, true, ServersModel::ServersModelRoles::IsDefaultRole); } return getPagePath(PageLoader::PageEnum::PageStart); } else { diff --git a/client/ui/controllers/pageController.h b/client/ui/controllers/pageController.h index f37edca9..1d041deb 100644 --- a/client/ui/controllers/pageController.h +++ b/client/ui/controllers/pageController.h @@ -9,7 +9,10 @@ namespace PageLoader { Q_NAMESPACE - enum class PageEnum { PageStart = 0, PageHome, PageSettings, PageShare, + enum class PageEnum { PageStart = 0, PageHome, PageShare, + + PageSettingsServersList, PageSettings, PageSettingsServerData, PageSettingsServerInfo, + PageSettingsServerProtocols, PageSettingsServerServices, PageSetupWizardStart, PageTest, PageSetupWizardCredentials, PageSetupWizardProtocols, PageSetupWizardEasy, PageSetupWizardProtocolSettings, PageSetupWizardInstalling, PageSetupWizardConfigSource, @@ -41,6 +44,8 @@ public slots: signals: void goToPageHome(); + void restorePageHomeState(bool isContainerInstalled = false); + void replaceStartPage(); void showErrorMessage(QString errorMessage); private: diff --git a/client/ui/models/containers_model.cpp b/client/ui/models/containers_model.cpp index 4dc7010e..b240878d 100644 --- a/client/ui/models/containers_model.cpp +++ b/client/ui/models/containers_model.cpp @@ -86,6 +86,7 @@ void ContainersModel::setCurrentlyProcessedServerIndex(int index) beginResetModel(); m_currentlyProcessedServerIndex = index; endResetModel(); + emit defaultContainerChanged(); } void ContainersModel::setCurrentlyInstalledContainerIndex(int index) @@ -115,7 +116,7 @@ void ContainersModel::removeAllContainers() auto errorCode = serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex)); if (errorCode == ErrorCode::NoError) { - beginResetModel(); + beginResetModel(); m_settings->setContainers(m_currentlyProcessedServerIndex, {}); m_settings->setDefaultContainer(m_currentlyProcessedServerIndex, DockerContainer::None); endResetModel(); @@ -124,6 +125,14 @@ void ContainersModel::removeAllContainers() //todo process errors } +void ContainersModel::clearCachedProfiles() +{ + const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex); + for (DockerContainer container : containers.keys()) { + m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container); + } +} + 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 642b6680..3ce7bd6b 100644 --- a/client/ui/models/containers_model.h +++ b/client/ui/models/containers_model.h @@ -49,6 +49,7 @@ public slots: int getCurrentlyInstalledContainerIndex(); void removeAllContainers(); + void clearCachedProfiles(); protected: QHash roleNames() const override; diff --git a/client/ui/models/servers_model.cpp b/client/ui/models/servers_model.cpp index 884009e8..d05bb695 100644 --- a/client/ui/models/servers_model.cpp +++ b/client/ui/models/servers_model.cpp @@ -17,15 +17,14 @@ bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int || index.row() >= static_cast(m_settings->serversCount())) { return false; } -// if (role == DescRole) { -// return m_data[index.row()].desc; -// } -// if (role == AddressRole) { -// return m_data[index.row()].address; -// } -// if (role == IsDefaultRole) { -// return m_data[index.row()].isDefault; -// } + + switch (role) { + case IsDefaultRole: m_settings->setDefaultServer(index.row()); + default: return true; + } + + emit dataChanged(index, index); + return true; } QVariant ServersModel::data(const QModelIndex &index, int role) const @@ -58,14 +57,6 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const return QVariant(); } -//todo mode to setData? -void ServersModel::setDefaultServerIndex(int index) -{ - // beginResetModel(); - m_settings->setDefaultServer(index); - // endResetModel(); -} - const int ServersModel::getDefaultServerIndex() { return m_settings->defaultServerIndex(); @@ -81,14 +72,38 @@ void ServersModel::setCurrentlyProcessedServerIndex(int index) m_currenlyProcessedServerIndex = index; } +bool ServersModel::isDefaultServerCurrentlyProcessed() +{ + return m_settings->defaultServerIndex() == m_currenlyProcessedServerIndex; +} + ServerCredentials ServersModel::getCurrentlyProcessedServerCredentials() { return qvariant_cast(data(index(m_currenlyProcessedServerIndex), CredentialsRole)); } -void ServersModel::addServer() +void ServersModel::addServer(const QJsonObject &server) { + beginResetModel(); + m_settings->addServer(server); + endResetModel(); +} +void ServersModel::removeServer() +{ + beginResetModel(); + m_settings->removeServer(m_currenlyProcessedServerIndex); + + if (m_settings->defaultServerIndex() == m_currenlyProcessedServerIndex) { + m_settings->setDefaultServer(0); + } else if (m_settings->defaultServerIndex() > m_currenlyProcessedServerIndex) { + m_settings->setDefaultServer(m_settings->defaultServerIndex() - 1); + } + + if (m_settings->serversCount() == 0) { + m_settings->setDefaultServer(-1); + } + endResetModel(); } QHash ServersModel::roleNames() const { diff --git a/client/ui/models/servers_model.h b/client/ui/models/servers_model.h index ae1ec8d9..54ac5ef4 100644 --- a/client/ui/models/servers_model.h +++ b/client/ui/models/servers_model.h @@ -31,15 +31,16 @@ public: QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; public slots: - void setDefaultServerIndex(int index); const int getDefaultServerIndex(); + bool isDefaultServerCurrentlyProcessed(); const int getServersCount(); void setCurrentlyProcessedServerIndex(int index); ServerCredentials getCurrentlyProcessedServerCredentials(); - void addServer(); + void addServer(const QJsonObject &server); + void removeServer(); protected: QHash roleNames() const override; diff --git a/client/ui/pages.h b/client/ui/pages.h index 82c0d409..f3d045b2 100644 --- a/client/ui/pages.h +++ b/client/ui/pages.h @@ -26,14 +26,7 @@ enum class Page { Start = 0, NewServer, NewServerProtocols, Vpn, GeneralSettings, AppSettings, NetworkSettings, ServerSettings, ServerContainers, ServersList, ShareConnection, Sites, ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About, ViewConfig, - AdvancedServerSettings, ClientManagement, ClientInfo, - - PageSetupWizardStart, PageTest, PageSetupWizardCredentials, PageSetupWizardProtocols, PageSetupWizardEasy, - PageSetupWizardProtocolSettings, PageSetupWizardInstalling, PageSetupWizardConfigSource, PageSetupWizardTextKey, - - PageSettings, PageSettingsServersList, - - PageStart, PageHome, PageShare}; + AdvancedServerSettings, ClientManagement, ClientInfo}; Q_ENUM_NS(Page) static void declareQmlPageEnum() { diff --git a/client/ui/qml/Components/ConnectButton.qml b/client/ui/qml/Components/ConnectButton.qml index 5002d5bd..73accef4 100644 --- a/client/ui/qml/Components/ConnectButton.qml +++ b/client/ui/qml/Components/ConnectButton.qml @@ -7,7 +7,7 @@ import ConnectionState 1.0 Button { id: root - text: "Подключиться" + text: qsTr("Connect") background: Image { id: border @@ -60,37 +60,37 @@ Button { case ConnectionState.Disconnected: { console.log("Disconnected") connectionProccess.running = false - root.text = "Подключиться" + root.text = qsTr("Connect") break } case ConnectionState.Preparing: { console.log("Preparing") connectionProccess.running = true - root.text = "Подключение..." + root.text = qsTr("Connection...") break } case ConnectionState.Connecting: { console.log("Connecting") connectionProccess.running = true - root.text = "Подключение..." + root.text = qsTr("Connection...") break } case ConnectionState.Connected: { console.log("Connected") connectionProccess.running = false - root.text = "Подключено" + root.text = qsTr("Connected") break } case ConnectionState.Disconnecting: { console.log("Disconnecting") connectionProccess.running = true - root.text = "Отключение..." + root.text = qsTr("Disconnection...") break } case ConnectionState.Reconnecting: { console.log("Reconnecting") connectionProccess.running = true - root.text = "Переподключение..." + root.text = qsTr("Reconnection...") break } case ConnectionState.Error: { diff --git a/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml b/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml index 2e6b3f2e..d80d5e5a 100644 --- a/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml +++ b/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml @@ -8,16 +8,12 @@ import "../Controls2" import "../Controls2/TextTypes" import "../Config" -Drawer { +DrawerType { id: root - edge: Qt.BottomEdge width: parent.width height: parent.height * 0.4375 - clip: true - modal: true - background: Rectangle { anchors.fill: parent anchors.bottomMargin: -radius diff --git a/client/ui/qml/Components/ContainersPageHomeListView.qml b/client/ui/qml/Components/HomeContainersListView.qml similarity index 52% rename from client/ui/qml/Components/ContainersPageHomeListView.qml rename to client/ui/qml/Components/HomeContainersListView.qml index f8b5101e..c3e98fbb 100644 --- a/client/ui/qml/Components/ContainersPageHomeListView.qml +++ b/client/ui/qml/Components/HomeContainersListView.qml @@ -29,64 +29,23 @@ ListView { implicitWidth: rootWidth implicitHeight: containerRadioButton.implicitHeight - RadioButton { + VerticalRadioButton { id: containerRadioButton - implicitWidth: parent.width - implicitHeight: containerRadioButtonContent.implicitHeight + anchors.fill: parent + anchors.rightMargin: 16 + anchors.leftMargin: 16 - hoverEnabled: true + text: name + descriptionText: description ButtonGroup.group: containersRadioButtonGroup - checked: isDefault - - indicator: Rectangle { - anchors.fill: parent - color: containerRadioButton.hovered ? "#2C2D30" : "#1C1D21" - - Behavior on color { - PropertyAnimation { duration: 200 } - } - } + imageSource: "qrc:/images/controls/download.svg" + showImage: !isInstalled checkable: isInstalled - - RowLayout { - id: containerRadioButtonContent - anchors.fill: parent - - anchors.rightMargin: 16 - anchors.leftMargin: 16 - - z: 1 - - Image { - source: isInstalled ? "qrc:/images/controls/check.svg" : "qrc:/images/controls/download.svg" - visible: isInstalled ? containerRadioButton.checked : true - - width: 24 - height: 24 - - Layout.rightMargin: 8 - } - - Text { - id: containerRadioButtonText - - text: name - 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 - } - } + checked: isDefault onClicked: { if (checked) { diff --git a/client/ui/qml/Components/PageSettingsContainersListView.qml b/client/ui/qml/Components/SettingsContainersListView.qml similarity index 97% rename from client/ui/qml/Components/PageSettingsContainersListView.qml rename to client/ui/qml/Components/SettingsContainersListView.qml index 2a59b8b2..5175fd49 100644 --- a/client/ui/qml/Components/PageSettingsContainersListView.qml +++ b/client/ui/qml/Components/SettingsContainersListView.qml @@ -14,6 +14,7 @@ import "../Controls2/TextTypes" ListView { id: root + width: parent.width height: root.contentItem.height clip: true @@ -23,7 +24,7 @@ ListView { } delegate: Item { - implicitWidth: parent.width + implicitWidth: root.width implicitHeight: containerRadioButton.implicitHeight RadioButton { diff --git a/client/ui/qml/Controls2/DrawerType.qml b/client/ui/qml/Controls2/DrawerType.qml new file mode 100644 index 00000000..bede3700 --- /dev/null +++ b/client/ui/qml/Controls2/DrawerType.qml @@ -0,0 +1,20 @@ +import QtQuick +import QtQuick.Controls + +Drawer { + edge: Qt.BottomEdge + + clip: true + modal: true + + enter: Transition { + SmoothedAnimation { + velocity: 4 + } + } + exit: Transition { + SmoothedAnimation { + velocity: 4 + } + } +} diff --git a/client/ui/qml/Controls2/DropDownType.qml b/client/ui/qml/Controls2/DropDownType.qml index 2b8986b5..5ac50fa7 100644 --- a/client/ui/qml/Controls2/DropDownType.qml +++ b/client/ui/qml/Controls2/DropDownType.qml @@ -111,16 +111,12 @@ Item { } } - Drawer { + DrawerType { id: menu - edge: Qt.BottomEdge width: parent.width height: parent.height * 0.9 - clip: true - modal: true - background: Rectangle { anchors.fill: parent anchors.bottomMargin: -radius diff --git a/client/ui/qml/Controls2/PageType.qml b/client/ui/qml/Controls2/PageType.qml index 4eb51753..046201b7 100644 --- a/client/ui/qml/Controls2/PageType.qml +++ b/client/ui/qml/Controls2/PageType.qml @@ -8,10 +8,11 @@ Item { property StackView stackView: StackView.view function goToPage(page, slide = true) { + var pagePath = PageController.getPagePath(page) if (slide) { - root.stackView.push(PageController.getPagePath(page), {}, StackView.PushTransition) + root.stackView.push(pagePath, { "objectName" : pagePath }, StackView.PushTransition) } else { - root.stackView.push(PageController.getPagePath(page), {}, StackView.Immediate) + root.stackView.push(pagePath, { "objectName" : pagePath }, StackView.Immediate) } } diff --git a/client/ui/qml/Controls2/StackViewType.qml b/client/ui/qml/Controls2/StackViewType.qml new file mode 100644 index 00000000..e2646e45 --- /dev/null +++ b/client/ui/qml/Controls2/StackViewType.qml @@ -0,0 +1,61 @@ +import QtQuick +import QtQuick.Controls + +StackView { + id: root + + pushEnter: Transition { + PropertyAnimation { + property: "opacity" + from: 0 + to:1 + duration: 200 + } + } + + pushExit: Transition { + PropertyAnimation { + property: "opacity" + from: 1 + to:0 + duration: 200 + } + } + + popEnter: Transition { + PropertyAnimation { + property: "opacity" + from: 0 + to:1 + duration: 200 + } + } + + popExit: Transition { + PropertyAnimation { + property: "opacity" + from: 1 + to:0 + duration: 200 + } + } + + replaceEnter: Transition { + PropertyAnimation { + property: "opacity" + from: 0 + to:1 + duration: 200 + } + } + + replaceExit: Transition { + PropertyAnimation { + property: "opacity" + from: 1 + to:0 + duration: 200 + } + } +} + diff --git a/client/ui/qml/Controls2/SwitcherType.qml b/client/ui/qml/Controls2/SwitcherType.qml index b593ece8..e4df04fa 100644 --- a/client/ui/qml/Controls2/SwitcherType.qml +++ b/client/ui/qml/Controls2/SwitcherType.qml @@ -59,6 +59,7 @@ Switch { } } + contentItem: ColumnLayout { contentItem: ColumnLayout { id: content diff --git a/client/ui/qml/Controls2/VerticalRadioButton.qml b/client/ui/qml/Controls2/VerticalRadioButton.qml index 420051cd..50af3c79 100644 --- a/client/ui/qml/Controls2/VerticalRadioButton.qml +++ b/client/ui/qml/Controls2/VerticalRadioButton.qml @@ -3,6 +3,8 @@ import QtQuick.Controls import QtQuick.Layouts import Qt5Compat.GraphicalEffects +import "TextTypes" + RadioButton { id: root @@ -13,7 +15,8 @@ RadioButton { property string disabledColor: Qt.rgba(1, 1, 1, 0) property string selectedColor: Qt.rgba(1, 1, 1, 0) - property string textColor: "#0E0E11" + property string textColor: "#D7D8DB" + property string selectedTextColor: "#FBB26A" property string pressedBorderColor: Qt.rgba(251/255, 178/255, 106/255, 0.3) property string selectedBorderColor: "#FBB26A" @@ -26,11 +29,16 @@ RadioButton { property string defaultInnerCircleColor: "#FBB26A" + property string imageSource + property bool showImage + hoverEnabled: true indicator: Rectangle { id: background + anchors.verticalCenter: parent.verticalCenter + implicitWidth: 56 implicitHeight: 56 radius: 16 @@ -52,6 +60,16 @@ RadioButton { PropertyAnimation { duration: 200 } } + Image { + source: imageSource + visible: showImage + + anchors.centerIn: parent + + width: 24 + height: 24 + } + Rectangle { id: outerCircle @@ -59,6 +77,8 @@ RadioButton { height: 24 radius: 16 + visible: !showImage + anchors.centerIn: parent color: "transparent" @@ -120,34 +140,41 @@ RadioButton { contentItem: ColumnLayout { id: content - anchors.fill: parent + anchors.left: parent.left + anchors.right: parent.right anchors.leftMargin: 8 + background.width - Text { - text: root.text - wrapMode: Text.WordWrap - color: "#D7D8DB" - font.pixelSize: 16 - font.weight: 400 - font.family: "PT Root UI VF" + spacing: 4 + + ListItemTitleType { + text: root.text + + color: { + if (root.checked) { + return selectedTextColor + } + return textColor + } - height: 24 Layout.fillWidth: true + Layout.topMargin: 16 + Layout.bottomMargin: description.visible ? 0 : 16 + + Behavior on color { + PropertyAnimation { duration: 200 } + } } - 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 } } diff --git a/client/ui/qml/Pages2/PageHome.qml b/client/ui/qml/Pages2/PageHome.qml index 1fba3bff..0ecbafcc 100644 --- a/client/ui/qml/Pages2/PageHome.qml +++ b/client/ui/qml/Pages2/PageHome.qml @@ -37,6 +37,17 @@ PageType { } } + Connections { + target: PageController + + function onRestorePageHomeState(isContainerInstalled) { + menu.visible = true + if (isContainerInstalled) { + containersDropDown.menuVisible = true + } + } + } + Rectangle { id: buttonBackground anchors.fill: buttonContent @@ -96,16 +107,12 @@ PageType { } } - Drawer { + DrawerType { id: menu - edge: Qt.BottomEdge width: parent.width height: parent.height * 0.90 - clip: true - modal: true - background: Rectangle { anchors.fill: parent anchors.bottomMargin: -radius @@ -180,7 +187,7 @@ PageType { containersDropDown.menuVisible = true } - listView: ContainersPageHomeListView { + listView: HomeContainersListView { rootWidth: root.width model: proxyContainersModel @@ -251,81 +258,63 @@ PageType { property variant delegateData: model implicitWidth: serversMenuContent.width - implicitHeight: serverRadioButton.implicitHeight + implicitHeight: serverRadioButtonContent.implicitHeight - RadioButton { - id: serverRadioButton + ColumnLayout { + id: serverRadioButtonContent + anchors.fill: parent - implicitWidth: parent.width - implicitHeight: serverRadioButtonContent.implicitHeight + anchors.rightMargin: 16 + anchors.leftMargin: 16 - hoverEnabled: true - - checked: index === serversMenuContent.currentIndex - - ButtonGroup.group: serversRadioButtonGroup - - indicator: Rectangle { - anchors.fill: parent - color: serverRadioButton.hovered ? "#2C2D30" : "#1C1D21" - - Behavior on color { - PropertyAnimation { duration: 200 } - } - } + spacing: 0 RowLayout { - id: serverRadioButtonContent - anchors.fill: parent - - anchors.rightMargin: 16 - anchors.leftMargin: 16 - - z: 1 - - Image { - source: "qrc:/images/controls/check.svg" - visible: serverRadioButton.checked - width: 24 - height: 24 - - Layout.rightMargin: 8 - } - - Text { - id: serverRadioButtonText - - text: name - color: "#D7D8DB" - font.pixelSize: 16 - font.weight: 400 - font.family: "PT Root UI VF" - - height: 24 + VerticalRadioButton { + id: serverRadioButton Layout.fillWidth: true - Layout.topMargin: 20 - Layout.bottomMargin: 20 + + text: name + descriptionText: "description" + + checked: index === serversMenuContent.currentIndex + + ButtonGroup.group: serversRadioButtonGroup + + onClicked: { + serversMenuContent.currentIndex = index + + isDefault = true + ContainersModel.setCurrentlyProcessedServerIndex(index) + } + + MouseArea { + anchors.fill: serverRadioButton + cursorShape: Qt.PointingHandCursor + enabled: false + } } ImageButtonType { image: "qrc:/images/controls/settings.svg" -// onClicked: + implicitWidth: 56 + implicitHeight: 56 + + z: 1 + + onClicked: function() { + ServersModel.setCurrentlyProcessedServerIndex(index) + ContainersModel.setCurrentlyProcessedServerIndex(index) + goToPage(PageEnum.PageSettingsServerInfo) + menu.visible = false + } } } - onClicked: { - serversMenuContent.currentIndex = index - - ServersModel.setDefaultServerIndex(index) - ContainersModel.setCurrentlyProcessedServerIndex(index) - } - - MouseArea { - anchors.fill: serverRadioButton - cursorShape: Qt.PointingHandCursor - enabled: false + DividerType { + Layout.fillWidth: true } } } diff --git a/client/ui/qml/Pages2/PageSettings.qml b/client/ui/qml/Pages2/PageSettings.qml index 57c252b4..d3b87c19 100644 --- a/client/ui/qml/Pages2/PageSettings.qml +++ b/client/ui/qml/Pages2/PageSettings.qml @@ -1,142 +1,109 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts - -import SortFilterProxyModel 0.2 +import QtQuick.Dialogs import PageEnum 1.0 -import ProtocolEnum 1.0 -import ContainerProps 1.0 -import ProtocolProps 1.0 import "./" import "../Controls2" import "../Controls2/TextTypes" import "../Config" -import "../Components" PageType { id: root - SortFilterProxyModel { - id: proxyServersModel - sourceModel: ServersModel - filters: [ - ValueFilter { - roleName: "isCurrentlyProcessed" - value: true - } - ] - } + FlickableType { + id: fl + anchors.top: root.top + anchors.bottom: root.bottom + contentHeight: content.height ColumnLayout { id: content - anchors.fill: parent + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right - spacing: 16 + HeaderType { + Layout.fillWidth: true + Layout.topMargin: 20 + Layout.rightMargin: 16 + Layout.leftMargin: 16 - Repeater { - id: header - model: proxyServersModel + headerText: qsTr("Settings") + } - delegate: HeaderType { - Layout.fillWidth: true - Layout.topMargin: 20 - Layout.leftMargin: 16 - Layout.rightMargin: 16 + LabelWithButtonType { + Layout.fillWidth: true + Layout.topMargin: 16 - actionButtonImage: "qrc:/images/controls/edit-3.svg" - backButtonImage: "qrc:/images/controls/arrow-left.svg" + text: qsTr("Servers") + buttonImage: "qrc:/images/controls/chevron-right.svg" + iconImage: "qrc:/images/controls/server.svg" - headerText: name - descriptionText: hostName - - actionButtonFunction: function() { - connectionTypeSelection.visible = true - } - - backButtonFunction: function() { - closePage() - } + clickedFunction: function() { + goToPage(PageEnum.PageSettingsServersList) } } - TabBar { - id: tabBar + DividerType {} + LabelWithButtonType { Layout.fillWidth: true - background: Rectangle { - color: "transparent" - } + text: qsTr("Connection") + buttonImage: "qrc:/images/controls/chevron-right.svg" + iconImage: "qrc:/images/controls/radio.svg" - TabButtonType { - isSelected: tabBar.currentIndex === 0 - text: qsTr("Protocols") - } - TabButtonType { - isSelected: tabBar.currentIndex === 1 - text: qsTr("Services") - } - TabButtonType { - isSelected: tabBar.currentIndex === 2 - text: qsTr("Data") + clickedFunction: function() { } } - StackLayout { - id: stackLayout - currentIndex: tabBar.currentIndex + DividerType {} + LabelWithButtonType { 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 - } - ] - } - } - } + text: qsTr("Application") + buttonImage: "qrc:/images/controls/chevron-right.svg" + iconImage: "qrc:/images/controls/app.svg" - 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 { - - } + clickedFunction: function() { + goToPage(PageEnum.PageSetupWizardTextKey) } } + + DividerType {} + + LabelWithButtonType { + Layout.fillWidth: true + + text: qsTr("Backup") + buttonImage: "qrc:/images/controls/chevron-right.svg" + iconImage: "qrc:/images/controls/save.svg" + + clickedFunction: function() { + goToPage(PageEnum.PageSetupWizardTextKey) + } + } + + DividerType {} + + LabelWithButtonType { + Layout.fillWidth: true + + text: qsTr("About AmneziaVPN") + buttonImage: "qrc:/images/controls/chevron-right.svg" + iconImage: "qrc:/images/controls/amnezia.svg" + + clickedFunction: function() { + goToPage(PageEnum.PageSetupWizardTextKey) + } + } + + DividerType {} } -// } + } } diff --git a/client/ui/qml/Pages2/PageSettingsData.qml b/client/ui/qml/Pages2/PageSettingsServerData.qml similarity index 67% rename from client/ui/qml/Pages2/PageSettingsData.qml rename to client/ui/qml/Pages2/PageSettingsServerData.qml index 74293aa5..3ab76299 100644 --- a/client/ui/qml/Pages2/PageSettingsData.qml +++ b/client/ui/qml/Pages2/PageSettingsServerData.qml @@ -33,6 +33,7 @@ PageType { descriptionText: "May be needed when changing other settings" clickedFunction: function() { + ContainersModel.clearCachedProfiles() } } @@ -45,6 +46,15 @@ PageType { textColor: "#EB5757" clickedFunction: function() { + if (ServersModel.isDefaultServerCurrentlyProcessed && ConnectionController.isConnected()) { + ConnectionController.closeVpnConnection() + } + ServersModel.removeServer() + if (!ServersModel.getServersCount()) { + PageController.replaceStartPage() + } else { + goToStartPage() + } } } @@ -57,6 +67,9 @@ PageType { textColor: "#EB5757" clickedFunction: function() { + if (ServersModel.isDefaultServerCurrentlyProcessed && ConnectionController.isConnected()) { + ConnectionController.closeVpnConnection() + } ContainersModel.removeAllContainers() } } diff --git a/client/ui/qml/Pages2/PageSettingsServerInfo.qml b/client/ui/qml/Pages2/PageSettingsServerInfo.qml new file mode 100644 index 00000000..29a0c3c1 --- /dev/null +++ b/client/ui/qml/Pages2/PageSettingsServerInfo.qml @@ -0,0 +1,134 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import SortFilterProxyModel 0.2 + +import PageEnum 1.0 +import ProtocolEnum 1.0 +import ContainerProps 1.0 +import ProtocolProps 1.0 + +import "./" +import "../Controls2" +import "../Controls2/TextTypes" +import "../Config" +import "../Components" + +PageType { + id: root + + SortFilterProxyModel { + id: proxyServersModel + sourceModel: ServersModel + filters: [ + ValueFilter { + roleName: "isCurrentlyProcessed" + value: true + } + ] + } + + ColumnLayout { + id: content + + anchors.fill: parent + + spacing: 16 + + Repeater { + id: header + model: proxyServersModel + + delegate: HeaderType { + Layout.fillWidth: true + Layout.topMargin: 20 + Layout.leftMargin: 16 + Layout.rightMargin: 16 + + actionButtonImage: "qrc:/images/controls/edit-3.svg" + backButtonImage: "qrc:/images/controls/arrow-left.svg" + + headerText: name + descriptionText: hostName + + actionButtonFunction: function() { + connectionTypeSelection.visible = true + } + + backButtonFunction: function() { + closePage() + } + } + } + + TabBar { + id: tabBar + + Layout.fillWidth: true + + background: Rectangle { + color: "transparent" + } + + TabButtonType { + isSelected: tabBar.currentIndex === 0 + text: qsTr("Protocols") +// onClicked: { +// tabBarStackView.goToTabBarPage(PageEnum.PageSettingsServerProtocols) +// } + } + TabButtonType { + isSelected: tabBar.currentIndex === 1 + text: qsTr("Services") +// onClicked: { +// tabBarStackView.goToTabBarPage(PageEnum.PageSettingsServerServices) +// } + } + TabButtonType { + isSelected: tabBar.currentIndex === 2 + text: qsTr("Data") +// onClicked: { +// tabBarStackView.goToTabBarPage(PageEnum.PageSettingsServerData) +// } + } + } + + StackLayout { + Layout.preferredWidth: root.width + Layout.preferredHeight: root.height - tabBar.implicitHeight - header.implicitHeight + + currentIndex: tabBar.currentIndex + + PageSettingsServerProtocols { + stackView: root.stackView + } + PageSettingsServerServices { + stackView: root.stackView + } + PageSettingsServerData { + stackView: root.stackView + } + } + +// StackViewType { +// id: tabBarStackView + +// Layout.preferredWidth: root.width +// Layout.preferredHeight: root.height - tabBar.implicitHeight - header.implicitHeight + +// function goToTabBarPage(page) { +// var pagePath = PageController.getPagePath(page) +// while (tabBarStackView.depth > 1) { +// tabBarStackView.pop() +// } +// tabBarStackView.replace(pagePath, { "objectName" : pagePath }) +// } + +// Component.onCompleted: { +// var pagePath = PageController.getPagePath(PageEnum.PageSettingsServerProtocols) +// tabBarStackView.push(pagePath, { "objectName" : pagePath }) +// } +// } + } +} diff --git a/client/ui/qml/Pages2/PageSettingsServerProtocols.qml b/client/ui/qml/Pages2/PageSettingsServerProtocols.qml new file mode 100644 index 00000000..e93aa528 --- /dev/null +++ b/client/ui/qml/Pages2/PageSettingsServerProtocols.qml @@ -0,0 +1,38 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import SortFilterProxyModel 0.2 + +import PageEnum 1.0 +import ProtocolEnum 1.0 +import ContainerProps 1.0 + +import "./" +import "../Controls2" +import "../Controls2/TextTypes" +import "../Config" +import "../Components" + +PageType { + id: root + + SortFilterProxyModel { + id: containersProxyModel + sourceModel: ContainersModel + filters: [ + ValueFilter { + roleName: "serviceType" + value: ProtocolEnum.Vpn + }, + ValueFilter { + roleName: "isSupported" + value: true + } + ] + } + + SettingsContainersListView { + model: containersProxyModel + } +} diff --git a/client/ui/qml/Pages2/PageSettingsServerServices.qml b/client/ui/qml/Pages2/PageSettingsServerServices.qml new file mode 100644 index 00000000..7351f585 --- /dev/null +++ b/client/ui/qml/Pages2/PageSettingsServerServices.qml @@ -0,0 +1,38 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import SortFilterProxyModel 0.2 + +import PageEnum 1.0 +import ProtocolEnum 1.0 +import ContainerProps 1.0 + +import "./" +import "../Controls2" +import "../Controls2/TextTypes" +import "../Config" +import "../Components" + +PageType { + id: root + + SortFilterProxyModel { + id: containersProxyModel + sourceModel: ContainersModel + filters: [ + ValueFilter { + roleName: "serviceType" + value: ProtocolEnum.Other + }, + ValueFilter { + roleName: "isSupported" + value: true + } + ] + } + + SettingsContainersListView { + model: containersProxyModel + } +} diff --git a/client/ui/qml/Pages2/PageSettingsServersList.qml b/client/ui/qml/Pages2/PageSettingsServersList.qml index 2344b7e8..63a40cc0 100644 --- a/client/ui/qml/Pages2/PageSettingsServersList.qml +++ b/client/ui/qml/Pages2/PageSettingsServersList.qml @@ -36,10 +36,6 @@ PageType { actionButtonFunction: function() { connectionTypeSelection.visible = true } - - backButtonFunction: function() { - PageController.goToPageHome() - } } ConnectionTypeSelectionDrawer { @@ -87,7 +83,8 @@ PageType { clickedFunction: function() { ServersModel.setCurrentlyProcessedServerIndex(index) - goToPage(PageEnum.PageSettings) + ContainersModel.setCurrentlyProcessedServerIndex(index) + goToPage(PageEnum.PageSettingsServerInfo) } } diff --git a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml index 006743d9..cf7b1d28 100644 --- a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml +++ b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml @@ -26,10 +26,26 @@ PageType { function onInstallContainerFinished() { goToStartPage() + if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageHome)) { + PageController.restorePageHomeState(true) + } else if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSettings)) { + goToPage(PageEnum.PageSettingsServersList, false) + goToPage(PageEnum.PageSettingsServerInfo, false) + } else { + goToPage(PageEnum.PageHome) + } } function onInstallServerFinished() { goToStartPage() + if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageHome)) { + PageController.restorePageHomeState() + } else if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSettings)) { + goToPage(PageEnum.PageSettingsServersList, false) + } else { + var pagePath = PageController.getPagePath(PageEnum.PageStart) + stackView.replace(pagePath, { "objectName" : pagePath }) + } } } diff --git a/client/ui/qml/Pages2/PageSetupWizardStart.qml b/client/ui/qml/Pages2/PageSetupWizardStart.qml index 804e145c..6358f00d 100644 --- a/client/ui/qml/Pages2/PageSetupWizardStart.qml +++ b/client/ui/qml/Pages2/PageSetupWizardStart.qml @@ -22,16 +22,6 @@ PageType { } } - Connections { - target: InstallController - - function onInstallServerFinished() { - //todo add smt like changeStartPage - goToStartPage() - goToPage(PageEnum.PageStart) - } - } - FlickableType { id: fl anchors.top: root.top diff --git a/client/ui/qml/Pages2/PageStart.qml b/client/ui/qml/Pages2/PageStart.qml index c50d4591..44577037 100644 --- a/client/ui/qml/Pages2/PageStart.qml +++ b/client/ui/qml/Pages2/PageStart.qml @@ -17,6 +17,7 @@ PageType { function onGoToPageHome() { tabBar.currentIndex = 0 + tabBarStackView.goToTabBarPage(PageController.getPagePath(PageEnum.PageHome)) } function onShowErrorMessage(errorMessage) { @@ -25,9 +26,8 @@ PageType { } } - StackLayout { - id: stackLayout - currentIndex: tabBar.currentIndex + StackViewType { + id: tabBarStackView anchors.top: parent.top anchors.right: parent.right @@ -37,20 +37,15 @@ PageType { width: parent.width height: root.height - tabBar.implicitHeight - StackView { - initialItem: PageHome { - id: pageHome - } + function goToTabBarPage(page) { + var pagePath = PageController.getPagePath(page) + tabBarStackView.clear(StackView.PopTransition) + tabBarStackView.replace(pagePath, { "objectName" : pagePath }) } - Item { - - } - - StackView { - initialItem: PageSettingsServersList { - id: pageSettingsServersList - } + Component.onCompleted: { + var pagePath = PageController.getPagePath(PageEnum.PageHome) + tabBarStackView.push(pagePath, { "objectName" : pagePath }) } } @@ -70,12 +65,12 @@ PageType { color: "#1C1D21" } - TabImageButtonType { isSelected: tabBar.currentIndex === 0 image: "qrc:/images/controls/home.svg" onClicked: { - pageSettingsServersList.goToStartPage() + tabBarStackView.goToTabBarPage(PageEnum.PageHome) + ContainersModel.setCurrentlyProcessedServerIndex(ServersModel.getDefaultServerIndex()) } } TabImageButtonType { @@ -86,7 +81,7 @@ PageType { isSelected: tabBar.currentIndex === 2 image: "qrc:/images/controls/settings-2.svg" onClicked: { - pageHome.goToStartPage() + tabBarStackView.goToTabBarPage(PageEnum.PageSettings) } } } diff --git a/client/ui/qml/main2.qml b/client/ui/qml/main2.qml index 5ca1b345..bda1c709 100644 --- a/client/ui/qml/main2.qml +++ b/client/ui/qml/main2.qml @@ -4,8 +4,10 @@ import QtQuick.Controls import QtQuick.Layouts import PageType 1.0 +import PageEnum 1.0 import "Config" +import "Controls2" Window { id: root @@ -27,9 +29,27 @@ Window { color: "#0E0E11" } - StackView { + StackViewType { + id: rootStackView + anchors.fill: parent focus: true - initialItem: PageController.getInitialPage() + + Component.onCompleted: { + var pagePath = PageController.getPagePath(PageEnum.PageStart) + rootStackView.push(pagePath, { "objectName" : pagePath }) + } + } + + Connections { + target: PageController + + function onReplaceStartPage() { + var pagePath = PageController.getInitialPage() + while (rootStackView.depth > 1) { + rootStackView.pop() + } + rootStackView.replace(pagePath, { "objectName" : pagePath }) + } } } diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index 1cb43ee8..a0cac1cd 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -149,13 +149,13 @@ void UiLogic::initializeUiLogic() connect(m_notificationHandler, &NotificationHandler::connectRequested, pageLogic(), &VpnLogic::onConnect); connect(m_notificationHandler, &NotificationHandler::disconnectRequested, pageLogic(), &VpnLogic::onDisconnect); - if (m_settings->serversCount() > 0) { - if (m_settings->defaultServerIndex() < 0) m_settings->setDefaultServer(0); - emit goToPage(Page::PageStart, true, false); - } - else { - emit goToPage(Page::PageSetupWizardStart, true, false); - } +// if (m_settings->serversCount() > 0) { +// if (m_settings->defaultServerIndex() < 0) m_settings->setDefaultServer(0); +// emit goToPage(Page::PageStart, true, false); +// } +// else { +// emit goToPage(Page::PageSetupWizardStart, true, false); +// } m_selectedServerIndex = m_settings->defaultServerIndex();