Files
amnezia-client/client/ui/qml/Pages2/PageShare.qml
T

594 lines
22 KiB
QML
Raw Normal View History

import QtQuick
2023-06-13 20:03:20 +09:00
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
2023-06-13 20:03:20 +09:00
import SortFilterProxyModel 0.2
2023-06-13 20:03:20 +09:00
import PageEnum 1.0
import ContainerProps 1.0
import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Components"
PageType {
id: root
enum ConfigType {
AmneziaConnection,
AmneziaFullAccess,
OpenVpn,
WireGuard
}
2023-11-21 20:13:51 +07:00
signal revokeConfig(int index)
onRevokeConfig: function(index) {
PageController.showBusyIndicator(true)
ExportController.revokeConfig(index,
ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
PageController.showBusyIndicator(false)
}
2023-06-13 20:03:20 +09:00
Connections {
target: ExportController
function onGenerateConfig(type) {
2023-11-21 20:13:51 +07:00
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
shareConnectionDrawer.needCloseButton = false
2023-07-04 09:58:19 +09:00
shareConnectionDrawer.open()
shareConnectionDrawer.contentVisible = false
PageController.showBusyIndicator(true)
switch (type) {
2023-11-21 20:13:51 +07:00
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(userNameTextField.textFieldText); break;
case PageShare.ConfigType.AmneziaFullAccess: {
if (Qt.platform.os === "android") {
ExportController.generateFullAccessConfigAndroid();
} else {
ExportController.generateFullAccessConfig();
}
break;
}
2023-08-22 14:37:29 +05:00
case PageShare.ConfigType.OpenVpn: {
2023-11-21 20:13:51 +07:00
ExportController.generateOpenVpnConfig(userNameTextField.textFieldText)
2023-08-22 14:37:29 +05:00
shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
shareConnectionDrawer.configExtension = ".ovpn"
shareConnectionDrawer.configFileName = "amnezia_for_openvpn"
break;
}
case PageShare.ConfigType.WireGuard: {
2023-11-21 20:13:51 +07:00
ExportController.generateWireGuardConfig(userNameTextField.textFieldText)
2023-08-22 14:37:29 +05:00
shareConnectionDrawer.configCaption = qsTr("Save WireGuard config")
shareConnectionDrawer.configExtension = ".conf"
shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
break;
}
2023-06-13 20:03:20 +09:00
}
2023-07-04 09:58:19 +09:00
PageController.showBusyIndicator(false)
shareConnectionDrawer.needCloseButton = true
PageController.showTopCloseButton(true)
2023-07-04 09:58:19 +09:00
shareConnectionDrawer.contentVisible = true
}
function onExportErrorOccurred(errorMessage) {
shareConnectionDrawer.close()
PageController.showErrorMessage(errorMessage)
2023-06-13 20:03:20 +09:00
}
}
property bool showContent: false
property bool shareButtonEnabled: true
2023-06-13 20:03:20 +09:00
property list<QtObject> connectionTypesModel: [
amneziaConnectionFormat
]
QtObject {
id: amneziaConnectionFormat
property string name: qsTr("For the AmneziaVPN app")
property var type: PageShare.ConfigType.AmneziaConnection
2023-06-13 20:03:20 +09:00
}
QtObject {
id: openVpnConnectionFormat
property string name: qsTr("OpenVpn native format")
property var type: PageShare.ConfigType.OpenVpn
2023-06-13 20:03:20 +09:00
}
QtObject {
id: wireGuardConnectionFormat
property string name: qsTr("WireGuard native format")
property var type: PageShare.ConfigType.WireGuard
2023-06-13 20:03:20 +09:00
}
FlickableType {
anchors.top: parent.top
anchors.bottom: parent.bottom
2023-06-13 20:03:20 +09:00
contentHeight: content.height
ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 16
anchors.leftMargin: 16
2023-08-26 10:08:50 +03:00
spacing: 0
2023-06-13 20:03:20 +09:00
HeaderType {
Layout.fillWidth: true
2023-08-26 10:08:50 +03:00
Layout.topMargin: 24
2023-06-13 20:03:20 +09:00
2023-10-21 18:32:30 +01:00
headerText: qsTr("Share VPN Access")
2023-06-13 20:03:20 +09:00
}
Rectangle {
id: accessTypeSelector
property int currentIndex
Layout.topMargin: 32
implicitWidth: accessTypeSelectorContent.implicitWidth
implicitHeight: accessTypeSelectorContent.implicitHeight
color: "#1C1D21"
radius: 16
RowLayout {
id: accessTypeSelectorContent
spacing: 0
HorizontalRadioButton {
checked: accessTypeSelector.currentIndex === 0
implicitWidth: (root.width - 32) / 2
text: qsTr("Connection")
onClicked: {
accessTypeSelector.currentIndex = 0
}
}
HorizontalRadioButton {
2023-11-21 20:13:51 +07:00
checked: accessTypeSelector.currentIndex === 1
2023-06-13 20:03:20 +09:00
implicitWidth: (root.width - 32) / 2
2023-11-21 20:13:51 +07:00
text: qsTr("Users")
2023-06-13 20:03:20 +09:00
onClicked: {
accessTypeSelector.currentIndex = 1
2023-11-21 20:13:51 +07:00
PageController.showBusyIndicator(true)
ClientManagementModel.updateModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
PageController.showBusyIndicator(false)
2023-06-13 20:03:20 +09:00
}
}
}
}
ParagraphTextType {
Layout.fillWidth: true
Layout.topMargin: 24
2023-08-26 10:08:50 +03:00
Layout.bottomMargin: 24
2023-06-13 20:03:20 +09:00
2023-11-21 20:13:51 +07:00
visible: accessTypeSelector.currentIndex === 0
text: qsTr("Share VPN access without the ability to manage the server")
2023-06-13 20:03:20 +09:00
color: "#878B91"
}
2023-11-21 20:13:51 +07:00
TextFieldWithHeaderType {
id: userNameTextField
Layout.fillWidth: true
Layout.topMargin: 16
visible: accessTypeSelector.currentIndex === 0
headerText: qsTr("User name")
textFieldText: "New client"
checkEmptyText: true
}
2023-06-13 20:03:20 +09:00
DropDownType {
id: serverSelector
signal severSelectorIndexChanged
property int currentIndex: 0
2023-06-13 20:03:20 +09:00
Layout.fillWidth: true
2023-08-26 10:08:50 +03:00
Layout.topMargin: 16
2023-06-13 20:03:20 +09:00
drawerHeight: 0.4375
descriptionText: qsTr("Server")
2023-06-13 20:03:20 +09:00
headerText: qsTr("Server")
listView: ListViewWithRadioButtonType {
id: serverSelectorListView
2023-06-13 20:03:20 +09:00
rootWidth: root.width
imageSource: "qrc:/images/controls/check.svg"
2023-06-13 20:03:20 +09:00
model: SortFilterProxyModel {
id: proxyServersModel
sourceModel: ServersModel
filters: [
ValueFilter {
roleName: "hasWriteAccess"
value: true
}
]
}
currentIndex: 0
2023-06-13 20:03:20 +09:00
clickedFunction: function() {
handler()
if (serverSelector.currentIndex !== serverSelectorListView.currentIndex) {
serverSelector.currentIndex = serverSelectorListView.currentIndex
serverSelector.severSelectorIndexChanged()
}
2023-11-21 20:13:51 +07:00
//full access label
// if (accessTypeSelector.currentIndex !== 0) {
// shareConnectionDrawer.headerText = qsTr("Accessing ") + serverSelector.text
// shareConnectionDrawer.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
// }
serverSelector.menuVisible = false
2023-06-13 20:03:20 +09:00
}
Component.onCompleted: {
handler()
serverSelector.severSelectorIndexChanged()
}
function handler() {
2023-06-13 20:03:20 +09:00
serverSelector.text = selectedText
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex)
2023-06-13 20:03:20 +09:00
}
}
}
DropDownType {
id: protocolSelector
2023-06-13 20:03:20 +09:00
Layout.fillWidth: true
Layout.topMargin: 16
drawerHeight: 0.5
2023-06-13 20:03:20 +09:00
2023-10-03 23:28:44 +05:00
descriptionText: qsTr("Protocol")
headerText: qsTr("Protocol")
2023-06-13 20:03:20 +09:00
listView: ListViewWithRadioButtonType {
id: protocolSelectorListView
2023-06-13 20:03:20 +09:00
rootWidth: root.width
imageSource: "qrc:/images/controls/check.svg"
2023-06-13 20:03:20 +09:00
model: SortFilterProxyModel {
id: proxyContainersModel
sourceModel: ContainersModel
filters: [
ValueFilter {
roleName: "isInstalled"
value: true
},
ValueFilter {
roleName: "isShareable"
value: true
2023-06-13 20:03:20 +09:00
}
]
}
currentIndex: 0
clickedFunction: function() {
handler()
protocolSelector.menuVisible = false
}
Connections {
target: serverSelector
2023-06-13 20:03:20 +09:00
function onSeverSelectorIndexChanged() {
protocolSelectorListView.currentIndex = 0
protocolSelectorListView.triggerCurrentItem()
}
}
2023-06-13 20:03:20 +09:00
function handler() {
if (!proxyContainersModel.count) {
root.shareButtonEnabled = false
return
} else {
root.shareButtonEnabled = true
}
2023-06-13 20:03:20 +09:00
protocolSelector.text = selectedText
2023-06-13 20:03:20 +09:00
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
2023-06-13 20:03:20 +09:00
2023-11-21 20:13:51 +07:00
if (accessTypeSelector.currentIndex === 0) {
fillConnectionTypeModel()
} else {
PageController.showBusyIndicator(true)
ClientManagementModel.updateModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
PageController.showBusyIndicator(false)
}
}
function fillConnectionTypeModel() {
root.connectionTypesModel = [amneziaConnectionFormat]
var index = proxyContainersModel.mapToSource(currentIndex)
if (index === ContainerProps.containerFromString("amnezia-openvpn")) {
root.connectionTypesModel.push(openVpnConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-wireguard")) {
root.connectionTypesModel.push(wireGuardConnectionFormat)
2023-06-13 20:03:20 +09:00
}
}
}
}
DropDownType {
id: exportTypeSelector
2023-06-13 20:03:20 +09:00
property int currentIndex: 0
2023-06-13 20:03:20 +09:00
Layout.fillWidth: true
Layout.topMargin: 16
drawerHeight: 0.4375
visible: accessTypeSelector.currentIndex === 0
enabled: root.connectionTypesModel.length > 1
2023-06-13 20:03:20 +09:00
descriptionText: qsTr("Connection format")
headerText: qsTr("Connection format")
2023-08-16 22:45:05 +05:00
listView: ListViewWithRadioButtonType {
onCurrentIndexChanged: {
exportTypeSelector.currentIndex = currentIndex
exportTypeSelector.text = selectedText
}
2023-06-13 20:03:20 +09:00
rootWidth: root.width
imageSource: "qrc:/images/controls/check.svg"
2023-06-13 20:03:20 +09:00
model: root.connectionTypesModel
currentIndex: 0
2023-06-13 20:03:20 +09:00
clickedFunction: function() {
exportTypeSelector.text = selectedText
exportTypeSelector.currentIndex = currentIndex
exportTypeSelector.menuVisible = false
2023-06-13 20:03:20 +09:00
}
Component.onCompleted: {
exportTypeSelector.text = selectedText
exportTypeSelector.currentIndex = currentIndex
2023-06-13 20:03:20 +09:00
}
}
}
ShareConnectionDrawer {
id: shareConnectionDrawer
}
BasicButtonType {
Layout.fillWidth: true
2023-08-26 10:08:50 +03:00
Layout.topMargin: 40
2023-06-13 20:03:20 +09:00
enabled: shareButtonEnabled
2023-11-21 20:13:51 +07:00
visible: accessTypeSelector.currentIndex === 0
2023-06-13 20:03:20 +09:00
text: qsTr("Share")
imageSource: "qrc:/images/controls/share-2.svg"
2023-06-13 20:03:20 +09:00
onClicked: {
2023-11-21 20:13:51 +07:00
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
}
}
Header2Type {
Layout.fillWidth: true
Layout.topMargin: 24
Layout.bottomMargin: 16
visible: accessTypeSelector.currentIndex === 1
headerText: qsTr("Users")
}
ListView {
id: usersListView
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
visible: accessTypeSelector.currentIndex === 1
model: ClientManagementModel
clip: true
interactive: false
delegate: Item {
implicitWidth: usersListView.width
implicitHeight: delegateContent.implicitHeight
ColumnLayout {
id: delegateContent
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: -16
anchors.leftMargin: -16
LabelWithButtonType {
Layout.fillWidth: true
text: userName
descriptionText: containerName
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
userInfoDrower.open()
}
}
DividerType {}
DrawerType {
id: userInfoDrower
width: root.width
height: root.height * 0.45
ColumnLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 16
anchors.leftMargin: 16
anchors.rightMargin: 16
spacing: 8
Header2Type {
Layout.fillWidth: true
Layout.bottomMargin: 24
headerText: userName
descriptionText: serverSelector.text + ", " + containerName
}
BasicButtonType {
Layout.fillWidth: true
Layout.topMargin: 24
defaultColor: "transparent"
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
pressedColor: Qt.rgba(1, 1, 1, 0.12)
disabledColor: "#878B91"
textColor: "#D7D8DB"
borderWidth: 1
text: qsTr("Rename")
onClicked: function() {
clientNameEditDrawer.open()
}
DrawerType {
id: clientNameEditDrawer
width: root.width
height: root.height * 0.35
onVisibleChanged: {
if (clientNameEditDrawer.visible) {
clientName.textField.forceActiveFocus()
}
}
ColumnLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 16
anchors.leftMargin: 16
anchors.rightMargin: 16
TextFieldWithHeaderType {
id: clientName
Layout.fillWidth: true
headerText: qsTr("Client name")
textFieldText: userName
}
BasicButtonType {
Layout.fillWidth: true
text: qsTr("Save")
onClicked: {
if (clientName.textFieldText !== userName) {
PageController.showBusyIndicator(true)
ExportController.renameClient(index,
clientName.textFieldText,
ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
PageController.showBusyIndicator(false)
clientNameEditDrawer.close()
}
}
}
}
}
}
BasicButtonType {
Layout.fillWidth: true
defaultColor: "transparent"
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
pressedColor: Qt.rgba(1, 1, 1, 0.12)
disabledColor: "#878B91"
textColor: "#D7D8DB"
borderWidth: 1
text: qsTr("Revoke")
onClicked: function() {
questionDrawer.headerText = qsTr("Revoke the config for a user - ") + userName + "?"
questionDrawer.descriptionText = qsTr("The user will no longer be able to connect to your server.")
questionDrawer.yesButtonText = qsTr("Continue")
questionDrawer.noButtonText = qsTr("Cancel")
questionDrawer.yesButtonFunction = function() {
questionDrawer.close()
userInfoDrower.close()
root.revokeConfig(index)
}
questionDrawer.noButtonFunction = function() {
questionDrawer.close()
}
questionDrawer.open()
}
}
}
}
2023-06-13 20:03:20 +09:00
}
}
}
2023-11-21 20:13:51 +07:00
QuestionDrawer {
id: questionDrawer
}
2023-06-13 20:03:20 +09:00
}
}
}