diff --git a/client/resources.qrc b/client/resources.qrc
index 54b5846c..4c15c6bb 100644
--- a/client/resources.qrc
+++ b/client/resources.qrc
@@ -127,7 +127,7 @@
ui/qml/Components/SelectLanguageDrawer.qml
ui/qml/Components/ServersListView.qml
ui/qml/Components/SettingsContainersListView.qml
- ui/qml/Components/ShareConnectionDrawer.qml
+
ui/qml/Components/TransportProtoSelector.qml
ui/qml/Components/AddSitePanel.qml
ui/qml/Config/GlobalConfig.qml
@@ -228,6 +228,7 @@
ui/qml/Pages2/PageSetupWizardViewConfig.qml
ui/qml/Pages2/PageShare.qml
ui/qml/Pages2/PageShareFullAccess.qml
+ ui/qml/Pages2/PageShareConnection.qml
ui/qml/Pages2/PageStart.qml
ui/qml/Components/RenameServerDrawer.qml
ui/qml/Controls2/ListViewType.qml
@@ -240,6 +241,7 @@
ui/qml/Components/ApiPremV1SubListDrawer.qml
ui/qml/Components/OtpCodeDrawer.qml
ui/qml/Components/AwgTextField.qml
+ ui/qml/Pages2/PageSettingsApiSubscriptionKey.qml
images/flagKit/ZW.svg
diff --git a/client/ui/controllers/pageController.h b/client/ui/controllers/pageController.h
index fc981091..1aee1ed7 100644
--- a/client/ui/controllers/pageController.h
+++ b/client/ui/controllers/pageController.h
@@ -38,6 +38,7 @@ namespace PageLoader
PageSettingsApiInstructions,
PageSettingsApiNativeConfigs,
PageSettingsApiDevices,
+ PageSettingsApiSubscriptionKey,
PageSettingsKillSwitchExceptions,
PageServiceSftpSettings,
@@ -71,6 +72,7 @@ namespace PageLoader
PageProtocolAwgClientSettings,
PageShareFullAccess,
+ PageShareConnection,
PageDevMenu
};
diff --git a/client/ui/qml/Components/ShareConnectionDrawer.qml b/client/ui/qml/Components/ShareConnectionDrawer.qml
deleted file mode 100644
index dd59180b..00000000
--- a/client/ui/qml/Components/ShareConnectionDrawer.qml
+++ /dev/null
@@ -1,375 +0,0 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import QtQuick.Dialogs
-
-import QtCore
-
-import SortFilterProxyModel 0.2
-
-import PageEnum 1.0
-import ContainerProps 1.0
-import Style 1.0
-
-import "./"
-import "../Controls2"
-import "../Controls2/TextTypes"
-import "../Config"
-import "../Components"
-
-DrawerType2 {
- id: root
-
- property string headerText
- property string configContentHeaderText
- property string shareButtonText: qsTr("Share")
- property string copyButtonText: qsTr("Copy")
- property bool isSelfHostedConfig: true
-
- property string configExtension: ".vpn"
- property string configCaption: qsTr("Save AmneziaVPN config")
- property string configFileName: "amnezia_config"
-
- expandedHeight: parent.height * 0.9
-
- onClosed: {
- configExtension = ".vpn"
- configCaption = qsTr("Save AmneziaVPN config")
- configFileName = "amnezia_config"
- }
-
- expandedStateContent: Item {
- implicitHeight: root.expandedHeight
-
- Header2Type {
- id: header
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 20
- anchors.leftMargin: 16
- anchors.rightMargin: 16
-
- headerText: root.headerText
- }
-
- ListView {
- id: listView
-
- anchors.top: header.bottom
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
-
- property bool isFocusable: true
-
- ScrollBar.vertical: ScrollBarType {}
-
- model: 1
-
- clip: true
- reuseItems: true
-
- header: ColumnLayout {
- width: listView.width
-
- BasicButtonType {
- id: shareButton
- Layout.fillWidth: true
- Layout.topMargin: 16
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- text: root.shareButtonText
- leftImageSource: "qrc:/images/controls/share-2.svg"
-
- clickedFunc: function() {
- var fileName = ""
- if (GC.isMobile()) {
- fileName = configFileName + configExtension
- } else {
- fileName = SystemController.getFileName(configCaption,
- qsTr("Config files (*" + configExtension + ")"),
- StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/" + configFileName,
- true,
- configExtension)
- }
- if (fileName !== "") {
- PageController.showBusyIndicator(true)
- ExportController.exportConfig(fileName)
- PageController.showBusyIndicator(false)
- }
- }
- }
-
- BasicButtonType {
- id: copyConfigTextButton
- Layout.fillWidth: true
- Layout.topMargin: 8
- 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: root.copyButtonText
- leftImageSource: "qrc:/images/controls/copy.svg"
-
- Keys.onReturnPressed: { copyConfigTextButton.clicked() }
- Keys.onEnterPressed: { copyConfigTextButton.clicked() }
- }
-
- BasicButtonType {
- id: copyNativeConfigStringButton
- Layout.fillWidth: true
- Layout.topMargin: 8
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- visible: false
-
- defaultColor: AmneziaStyle.color.transparent
- hoveredColor: AmneziaStyle.color.translucentWhite
- pressedColor: AmneziaStyle.color.sheerWhite
- disabledColor: AmneziaStyle.color.mutedGray
- textColor: AmneziaStyle.color.paleGray
- borderWidth: 1
-
- text: qsTr("Copy config string")
- leftImageSource: "qrc:/images/controls/copy.svg"
-
- KeyNavigation.tab: showSettingsButton
- }
-
- BasicButtonType {
- id: showSettingsButton
-
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- visible: root.isSelfHostedConfig
-
- defaultColor: AmneziaStyle.color.transparent
- hoveredColor: AmneziaStyle.color.translucentWhite
- pressedColor: AmneziaStyle.color.sheerWhite
- disabledColor: AmneziaStyle.color.mutedGray
- textColor: AmneziaStyle.color.paleGray
- borderWidth: 1
-
- text: qsTr("Show connection settings")
-
- clickedFunc: function() {
- configContentDrawer.openTriggered()
- }
- }
-
- DrawerType2 {
- id: configContentDrawer
-
- parent: root.parent
-
- anchors.fill: parent
- expandedHeight: parent.height * 0.9
-
- expandedStateContent: Item {
- id: configContentContainer
-
- implicitHeight: configContentDrawer.expandedHeight
-
- Connections {
- target: copyNativeConfigStringButton
- function onClicked() {
- nativeConfigString.selectAll()
- nativeConfigString.copy()
- nativeConfigString.select(0, 0)
- PageController.showNotificationMessage(qsTr("Copied"))
- }
- }
-
- Connections {
- target: copyConfigTextButton
- function onClicked() {
- configText.selectAll()
- configText.copy()
- configText.select(0, 0)
- PageController.showNotificationMessage(qsTr("Copied"))
- header.forceActiveFocus()
- }
- }
-
- BackButtonType {
- id: backButton
-
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: 16
-
- backButtonFunction: function() { configContentDrawer.closeTriggered() }
- }
-
- FlickableType {
- anchors.top: backButton.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- contentHeight: configContent.implicitHeight + configContent.anchors.topMargin + configContent.anchors.bottomMargin
-
- ColumnLayout {
- id: configContent
-
- anchors.fill: parent
- anchors.rightMargin: 16
- anchors.leftMargin: 16
-
- Header2Type {
- id: configContentHeader
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- headerText: root.configContentHeaderText
- }
-
- TextField {
- id: nativeConfigString
- visible: false
- text: ExportController.nativeConfigString
-
- onTextChanged: {
- copyNativeConfigStringButton.visible = nativeConfigString.text !== ""
- }
- }
-
- TextArea {
- id: configText
-
- Layout.fillWidth: true
- Layout.topMargin: 16
- Layout.bottomMargin: 16
-
- padding: 0
- leftPadding: 0
- height: 24
-
- readOnly: true
- activeFocusOnTab: false
-
- 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: ExportController.config
-
- wrapMode: Text.Wrap
-
- background: Rectangle {
- color: AmneziaStyle.color.transparent
- }
- }
- }
- }
- }
- }
- }
-
- delegate: ColumnLayout {
- width: listView.width
-
- property bool isQrCodeVisible: root.isSelfHostedConfig ? ExportController.qrCodesCount > 0 : ApiConfigsController.qrCodesCount > 0
-
- Rectangle {
- id: qrCodeContainer
-
- Layout.fillWidth: true
- Layout.preferredHeight: width
- Layout.topMargin: 20
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- visible: isQrCodeVisible
-
- color: "white"
-
- Image {
- anchors.fill: parent
- smooth: false
-
- source: root.isSelfHostedConfig ? (isQrCodeVisible ? ExportController.qrCodes[0] : "") :
- (isQrCodeVisible ? ApiConfigsController.qrCodes[0] : "")
-
- 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()
- }
-
- Timer {
- property int index: 0
- interval: 1000
- running: isQrCodeVisible
- repeat: true
- onTriggered: {
- if (isQrCodeVisible) {
- index++
- let qrCodesCount = root.isSelfHostedConfig ? ExportController.qrCodesCount : ApiConfigsController.qrCodesCount
- if (index >= qrCodesCount) {
- index = 0
- }
-
- parent.source = root.isSelfHostedConfig ? ExportController.qrCodes[index] : ApiConfigsController.qrCodes[index]
- }
- }
- }
-
- Behavior on source {
- PropertyAnimation { duration: 200 }
- }
- }
- }
-
- ParagraphTextType {
- Layout.fillWidth: true
- Layout.topMargin: 24
- Layout.bottomMargin: 32
- Layout.leftMargin: 16
- Layout.rightMargin: 16
-
- visible: isQrCodeVisible
-
- horizontalAlignment: Text.AlignHCenter
- text: qsTr("To read the QR code in the Amnezia app, select \"Add server\" → \"I have data to connect\" → \"QR code, key or settings file\"")
- }
- }
- }
- }
-}
diff --git a/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml b/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml
index 75832fa6..48fcfa11 100644
--- a/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml
+++ b/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml
@@ -111,17 +111,6 @@ PageType {
serverNameEditDrawer.openTriggered()
}
}
-
- RenameServerDrawer {
- id: serverNameEditDrawer
-
- parent: root
-
- anchors.fill: parent
- expandedHeight: root.height * 0.35
-
- serverNameText: root.processedServer.name
- }
}
delegate: ColumnLayout {
@@ -207,35 +196,30 @@ PageType {
Layout.fillWidth: true
Layout.topMargin: warning.visible ? 16 : 32
- visible: false //footer.isVisibleForAmneziaFree
+ visible: footer.isVisibleForAmneziaFree
text: qsTr("Subscription Key")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
- shareConnectionDrawer.headerText = qsTr("Amnezia Premium subscription key")
-
- shareConnectionDrawer.openTriggered()
- shareConnectionDrawer.isSelfHostedConfig = false;
- shareConnectionDrawer.shareButtonText = qsTr("Save VPN key as a file")
- shareConnectionDrawer.copyButtonText = qsTr("Copy VPN key")
-
-
+ PageController.goToPage(PageEnum.PageSettingsApiSubscriptionKey)
PageController.showBusyIndicator(true)
ApiConfigsController.prepareVpnKeyExport()
PageController.showBusyIndicator(false)
+
+ // Navigate to PageShareConnection page
+ //PageController.goToPage(PageEnum.PageShareConnection)
}
}
DividerType {
- visible: false //footer.isVisibleForAmneziaFree
+ visible: footer.isVisibleForAmneziaFree
}
LabelWithButtonType {
Layout.fillWidth: true
- Layout.topMargin: warning.visible ? 16 : 32
visible: footer.isVisibleForAmneziaFree
@@ -420,9 +404,12 @@ PageType {
}
}
- ShareConnectionDrawer {
- id: shareConnectionDrawer
+ RenameServerDrawer {
+ id: serverNameEditDrawer
anchors.fill: parent
+ expandedHeight: parent.height * 0.35
+
+ serverNameText: root.processedServer.name
}
}
diff --git a/client/ui/qml/Pages2/PageSettingsApiSubscriptionKey.qml b/client/ui/qml/Pages2/PageSettingsApiSubscriptionKey.qml
new file mode 100644
index 00000000..eace92ed
--- /dev/null
+++ b/client/ui/qml/Pages2/PageSettingsApiSubscriptionKey.qml
@@ -0,0 +1,204 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Dialogs
+import Qt.labs.platform 1.1
+
+import QtCore
+
+import PageEnum 1.0
+import Style 1.0
+
+import "../Controls2"
+import "../Controls2/TextTypes"
+import "../Config"
+import "../Components"
+
+PageType {
+ id: root
+
+ Component.onCompleted: {
+ PageController.showBusyIndicator(true)
+ ApiConfigsController.prepareVpnKeyExport()
+ PageController.showBusyIndicator(false)
+ }
+
+ FlickableType {
+ anchors.fill: parent
+ contentHeight: layout.implicitHeight
+
+ ColumnLayout {
+ id: layout
+ width: root.width
+
+ BackButtonType {
+ Layout.topMargin: 20
+ }
+
+ Label {
+ Layout.fillWidth: true
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ Layout.topMargin: 16
+ text: qsTr("Amnezia Premium\nsubscription key")
+ font.pixelSize: 32
+ font.bold: true
+ color: AmneziaStyle.color.paleGray
+ wrapMode: Text.Wrap
+ }
+
+ BasicButtonType {
+ Layout.fillWidth: true
+ Layout.topMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ defaultColor: AmneziaStyle.color.paleGray
+ hoveredColor: AmneziaStyle.color.sheerWhite
+ pressedColor: AmneziaStyle.color.translucentWhite
+ disabledColor: AmneziaStyle.color.mutedGray
+ textColor: AmneziaStyle.color.black
+ leftImageColor: "black"
+ borderWidth: 1
+
+ text: qsTr("Copy key")
+ leftImageSource: "qrc:/images/controls/copy.svg"
+
+ onClicked: {
+ ApiConfigsController.copyVpnKeyToClipboard()
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ BasicButtonType {
+ Layout.fillWidth: true
+ Layout.topMargin: 4
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ defaultColor: "transparent"
+ hoveredColor: AmneziaStyle.color.translucentWhite
+ pressedColor: AmneziaStyle.color.sheerWhite
+ textColor: AmneziaStyle.color.paleGray
+ borderWidth: 1
+
+ text: qsTr("Save key as a file")
+ leftImageSource: "qrc:/images/controls/share-2.svg"
+
+ onClicked: {
+ var fileName = GC.isMobile()
+ ? "amnezia_vpn_key.vpn"
+ : SystemController.getFileName(
+ qsTr("Save AmneziaVPN config"),
+ qsTr("Config files (*.vpn)"),
+ StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/amnezia_vpn_key",
+ true,
+ ".vpn"
+ )
+
+ if (fileName !== "") {
+ PageController.showBusyIndicator(true)
+ ExportController.exportConfig(fileName)
+ PageController.showBusyIndicator(false)
+ }
+ }
+ }
+
+ BasicButtonType {
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ defaultColor: "transparent"
+ hoveredColor: AmneziaStyle.color.translucentWhite
+ pressedColor: AmneziaStyle.color.sheerWhite
+ textColor: AmneziaStyle.color.paleGray
+ borderWidth: 1
+
+ text: qsTr("Show key text")
+ leftImageSource: "qrc:/images/controls/eye.svg"
+
+ onClicked: {
+ PageController.showBusyIndicator(true)
+ ApiConfigsController.prepareVpnKeyExport()
+ PageController.showBusyIndicator(false)
+ vpnKeyDrawer.openTriggered()
+ }
+ }
+
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: width
+ Layout.topMargin: 20
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ visible: ApiConfigsController.qrCodesCount > 0
+ color: "white"
+ radius: 12
+
+ Image {
+ anchors.fill: parent
+ smooth: false
+ source: ApiConfigsController.qrCodesCount > 0 && ApiConfigsController.qrCodes[0] ? ApiConfigsController.qrCodes[0] : ""
+ }
+ }
+
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ visible: ApiConfigsController.qrCodesCount > 0
+ horizontalAlignment: Text.AlignHCenter
+ text: qsTr("To read the QR code in the Amnezia app, tap + in the main menu → 'QR code'")
+ }
+ }
+ }
+
+ DrawerType2 {
+ id: vpnKeyDrawer
+
+ anchors.fill: root
+ expandedHeight: root.height * 0.9
+
+ expandedStateContent: Item {
+ BackButtonType {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.topMargin: 16
+ backButtonFunction: function() { vpnKeyDrawer.closeTriggered() }
+ }
+
+ ColumnLayout {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 56
+ anchors.leftMargin: 16
+ anchors.rightMargin: 16
+
+ Header2Type {
+ Layout.fillWidth: true
+ headerText: qsTr("Amnezia Premium Subscription key")
+ }
+
+ TextArea {
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ readOnly: true
+ 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: ApiConfigsController.vpnKey //|| ""
+ wrapMode: Text.Wrap
+ background: Rectangle { color: AmneziaStyle.color.transparent }
+ }
+ }
+ }
+ }
+}
diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml
index 21a5771c..327b59b6 100644
--- a/client/ui/qml/Pages2/PageShare.qml
+++ b/client/ui/qml/Pages2/PageShare.qml
@@ -15,6 +15,7 @@ import "../Controls2/TextTypes"
import "../Components"
import "../Config"
+
PageType {
id: root
@@ -42,10 +43,6 @@ PageType {
target: ExportController
function onGenerateConfig(type) {
- shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
- shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
-
- shareConnectionDrawer.openTriggered()
PageController.showBusyIndicator(true)
switch (type) {
@@ -55,54 +52,36 @@ PageType {
}
case PageShare.ConfigType.OpenVpn: {
ExportController.generateOpenVpnConfig(clientNameTextField.textField.text)
- shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
- shareConnectionDrawer.configExtension = ".ovpn"
- shareConnectionDrawer.configFileName = "amnezia_for_openvpn"
break
}
case PageShare.ConfigType.WireGuard: {
ExportController.generateWireGuardConfig(clientNameTextField.textField.text)
- shareConnectionDrawer.configCaption = qsTr("Save WireGuard config")
- shareConnectionDrawer.configExtension = ".conf"
- shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
break
}
case PageShare.ConfigType.Awg: {
ExportController.generateAwgConfig(clientNameTextField.textField.text)
- shareConnectionDrawer.configCaption = qsTr("Save AmneziaWG config")
- shareConnectionDrawer.configExtension = ".conf"
- shareConnectionDrawer.configFileName = "amnezia_for_awg"
break
}
case PageShare.ConfigType.ShadowSocks: {
ExportController.generateShadowSocksConfig()
- shareConnectionDrawer.configCaption = qsTr("Save Shadowsocks config")
- shareConnectionDrawer.configExtension = ".json"
- shareConnectionDrawer.configFileName = "amnezia_for_shadowsocks"
break
}
case PageShare.ConfigType.Cloak: {
ExportController.generateCloakConfig()
- shareConnectionDrawer.configCaption = qsTr("Save Cloak config")
- shareConnectionDrawer.configExtension = ".json"
- shareConnectionDrawer.configFileName = "amnezia_for_cloak"
break
}
case PageShare.ConfigType.Xray: {
ExportController.generateXrayConfig(clientNameTextField.textField.text)
- shareConnectionDrawer.configCaption = qsTr("Save XRay config")
- shareConnectionDrawer.configExtension = ".json"
- shareConnectionDrawer.configFileName = "amnezia_for_xray"
break
}
}
PageController.showBusyIndicator(false)
+
+ PageController.goToPage(PageEnum.PageShareConnection)
}
function onExportErrorOccurred(error) {
- shareConnectionDrawer.closeTriggered()
-
PageController.showErrorMessage(error)
}
}
@@ -832,9 +811,6 @@ PageType {
root.revokeConfig(index)
}
var noButtonFunction = function() {
- if (!GC.isMobile()) {
- // focusItem1.forceActiveFocus()
- }
}
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
@@ -848,9 +824,4 @@ PageType {
}
}
- ShareConnectionDrawer {
- id: shareConnectionDrawer
-
- anchors.fill: parent
- }
}
diff --git a/client/ui/qml/Pages2/PageShareConnection.qml b/client/ui/qml/Pages2/PageShareConnection.qml
new file mode 100644
index 00000000..9bc81ca3
--- /dev/null
+++ b/client/ui/qml/Pages2/PageShareConnection.qml
@@ -0,0 +1,329 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Dialogs
+
+import QtCore
+
+import SortFilterProxyModel 0.2
+
+import PageEnum 1.0
+import ContainerProps 1.0
+import Style 1.0
+
+import "./"
+import "../Controls2"
+import "../Controls2/TextTypes"
+import "../Config"
+import "../Components"
+
+PageType {
+ id: pageShareConnection
+
+ property string headerText
+
+ Component.onCompleted: {
+ var serverName = ServersModel.getProcessedServerData("name") || ServersModel.getProcessedServerData("hostName") || "Server"
+ headerText = qsTr("Connection to ") + serverName
+ configContentHeaderText = qsTr("File with connection settings to ") + serverName
+ }
+ property string configContentHeaderText
+ property string shareButtonText: qsTr("Share")
+ property string copyButtonText: qsTr("Copy")
+ property bool isSelfHostedConfig: true
+
+ property string configExtension: ".vpn"
+ property string configCaption: qsTr("Save AmneziaVPN config")
+ property string configFileName: "amnezia_config"
+
+ onVisibleChanged: {
+ configExtension = ".vpn"
+ configCaption = qsTr("Save AmneziaVPN config")
+ configFileName = "amnezia_config"
+
+ if (visible) {
+ var serverName = ServersModel.getProcessedServerData("name") || ServersModel.getProcessedServerData("hostName") || "Server"
+ headerText = qsTr("Connection to ") + serverName
+ configContentHeaderText = qsTr("File with connection settings to ") + serverName
+ }
+ }
+
+ BackButtonType {
+ id: backButton
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
+ }
+
+ Text {
+ id: shareHeader
+ anchors.top: backButton.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
+ anchors.leftMargin: 16
+ anchors.rightMargin: 16
+
+ text: pageShareConnection.headerText
+ color: AmneziaStyle.color.paleGray
+ font.pixelSize: 32
+ font.weight: 700
+ font.family: "PT Root UI VF"
+ wrapMode: Text.WordWrap
+ }
+
+ ListView {
+ id: listView
+
+ anchors.top: shareHeader.bottom
+ anchors.topMargin: 16
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ property bool isFocusable: true
+
+ ScrollBar.vertical: ScrollBarType {}
+ model: 1
+ clip: true
+ reuseItems: true
+
+ header: ColumnLayout {
+ width: listView.width
+
+ BasicButtonType {
+ id: shareButton
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ text: pageShareConnection.shareButtonText
+ leftImageSource: "qrc:/images/controls/share-2.svg"
+ clickedFunc: function() {
+ var fileName = ""
+ if (GC.isMobile()) {
+ fileName = configFileName + configExtension
+ } else {
+ fileName = SystemController.getFileName(configCaption,
+ qsTr("Config files (*" + configExtension + ")"),
+ StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/" + configFileName,
+ true,
+ configExtension)
+ }
+ if (fileName !== "") {
+ PageController.showBusyIndicator(true)
+ ExportController.exportConfig(fileName)
+ PageController.showBusyIndicator(false)
+ }
+ }
+ }
+
+ BasicButtonType {
+ id: copyConfigTextButton
+ Layout.fillWidth: true
+ Layout.topMargin: 8
+ 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: pageShareConnection.copyButtonText
+ leftImageSource: "qrc:/images/controls/copy.svg"
+
+ Keys.onReturnPressed: copyConfigTextButton.clicked()
+ Keys.onEnterPressed: copyConfigTextButton.clicked()
+ }
+
+ BasicButtonType {
+ id: copyNativeConfigStringButton
+ Layout.fillWidth: true
+ Layout.topMargin: 8
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ visible: false
+ defaultColor: AmneziaStyle.color.transparent
+ hoveredColor: AmneziaStyle.color.translucentWhite
+ pressedColor: AmneziaStyle.color.sheerWhite
+ disabledColor: AmneziaStyle.color.mutedGray
+ textColor: AmneziaStyle.color.paleGray
+ borderWidth: 1
+ text: qsTr("Copy config string")
+ leftImageSource: "qrc:/images/controls/copy.svg"
+ KeyNavigation.tab: showSettingsButton
+ }
+
+ BasicButtonType {
+ id: showSettingsButton
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ visible: pageShareConnection.isSelfHostedConfig
+ defaultColor: AmneziaStyle.color.transparent
+ hoveredColor: AmneziaStyle.color.translucentWhite
+ pressedColor: AmneziaStyle.color.sheerWhite
+ disabledColor: AmneziaStyle.color.mutedGray
+ textColor: AmneziaStyle.color.paleGray
+ borderWidth: 1
+ text: qsTr("Show connection settings")
+ clickedFunc: function() {
+ configContentDrawer.openTriggered()
+ }
+ }
+
+ DrawerType2 {
+ id: configContentDrawer
+ parent: pageShareConnection.parent
+ anchors.fill: parent
+ expandedHeight: parent.height * 0.9
+ expandedStateContent: Item {
+ id: configContentContainer
+ implicitHeight: configContentDrawer.expandedHeight
+
+ Connections {
+ target: copyNativeConfigStringButton
+ function onClicked() {
+ nativeConfigString.selectAll()
+ nativeConfigString.copy()
+ nativeConfigString.select(0, 0)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ }
+ }
+
+ Connections {
+ target: copyConfigTextButton
+ function onClicked() {
+ configText.selectAll()
+ configText.copy()
+ configText.select(0, 0)
+ PageController.showNotificationMessage(qsTr("Copied"))
+ header.forceActiveFocus()
+ }
+ }
+
+ BackButtonType {
+ id: configBackButton
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 16
+ backButtonFunction: function() { configContentDrawer.closeTriggered() }
+ }
+
+ FlickableType {
+ anchors.top: configBackButton.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ contentHeight: configContent.implicitHeight + configContent.anchors.topMargin + configContent.anchors.bottomMargin
+
+ ColumnLayout {
+ id: configContent
+ anchors.fill: parent
+ anchors.rightMargin: 16
+ anchors.leftMargin: 16
+
+ Header2Type {
+ id: configContentHeader
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ headerText: pageShareConnection.configContentHeaderText
+ }
+
+ TextField {
+ id: nativeConfigString
+ visible: false
+ text: ExportController.nativeConfigString
+ onTextChanged: copyNativeConfigStringButton.visible = nativeConfigString.text !== ""
+ }
+
+ TextArea {
+ id: configText
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+ Layout.bottomMargin: 16
+ padding: 0
+ leftPadding: 0
+ height: 24
+ readOnly: true
+ activeFocusOnTab: false
+ 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: ExportController.config
+ wrapMode: Text.Wrap
+ background: Rectangle { color: AmneziaStyle.color.transparent }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ delegate: ColumnLayout {
+ width: listView.width
+ property bool isQrCodeVisible: pageShareConnection.isSelfHostedConfig ? ExportController.qrCodesCount > 0 : ApiConfigsController.qrCodesCount > 0
+
+ Rectangle {
+ id: qrCodeContainer
+ Layout.fillWidth: true
+ Layout.preferredHeight: width
+ Layout.topMargin: 20
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ visible: isQrCodeVisible
+ color: "white"
+
+ Image {
+ anchors.fill: parent
+ smooth: false
+ source: pageShareConnection.isSelfHostedConfig ? (isQrCodeVisible ? ExportController.qrCodes[0] : "") : (isQrCodeVisible ? ApiConfigsController.qrCodes[0] : "")
+ 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()
+
+ Timer {
+ property int index: 0
+ interval: 1000
+ running: isQrCodeVisible
+ repeat: true
+ onTriggered: {
+ if (isQrCodeVisible) {
+ index++
+ let qrCodesCount = pageShareConnection.isSelfHostedConfig ? ExportController.qrCodesCount : ApiConfigsController.qrCodesCount
+ if (index >= qrCodesCount) index = 0
+ parent.source = pageShareConnection.isSelfHostedConfig ? ExportController.qrCodes[index] : ApiConfigsController.qrCodes[index]
+ }
+ }
+ }
+
+ Behavior on source { PropertyAnimation { duration: 200 } }
+ }
+ }
+
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 32
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ visible: isQrCodeVisible
+ horizontalAlignment: Text.AlignHCenter
+ text: qsTr("To read the QR code in the Amnezia app, select \"Add server\" → \"I have data to connect\" → \"QR code, key or settings file\"")
+ }
+ }
+ }
+}
diff --git a/client/ui/qml/Pages2/PageShareFullAccess.qml b/client/ui/qml/Pages2/PageShareFullAccess.qml
index 82effb57..062d0d1b 100644
--- a/client/ui/qml/Pages2/PageShareFullAccess.qml
+++ b/client/ui/qml/Pages2/PageShareFullAccess.qml
@@ -15,6 +15,7 @@ import "../Controls2/TextTypes"
import "../Components"
import "../Config"
+
PageType {
id: root
@@ -100,8 +101,8 @@ PageType {
serverSelector.currentIndex = serverSelectorListView.currentIndex
}
- shareConnectionDrawer.headerText = qsTr("Accessing ") + serverSelector.text
- shareConnectionDrawer.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
+ shareConnectionPage.headerText = qsTr("Accessing ") + serverSelector.text
+ shareConnectionPage.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
serverSelector.closeTriggered()
}
@@ -137,20 +138,13 @@ PageType {
ExportController.generateFullAccessConfig()
}
- shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
- shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
-
- shareConnectionDrawer.openTriggered()
-
PageController.showBusyIndicator(false)
+
+ PageController.goToPage(PageEnum.PageShareConnection)
}
}
}
}
- ShareConnectionDrawer {
- id: shareConnectionDrawer
-
- anchors.fill: parent
- }
}
+