import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Dialogs import SortFilterProxyModel 0.2 import PageEnum 1.0 import Style 1.0 import "./" import "../Controls2" import "../Controls2/TextTypes" import "../Config" import "../Components" PageType { id: root property list labelsModel: [ statusObject, endDateObject, deviceCountObject ] QtObject { id: statusObject readonly property string title: qsTr("Subscription Status") readonly property string contentKey: "subscriptionStatus" readonly property string objectImageSource: "qrc:/images/controls/info.svg" readonly property bool isRichText: true } QtObject { id: endDateObject readonly property string title: qsTr("Valid Until") readonly property string contentKey: "endDate" readonly property string objectImageSource: "qrc:/images/controls/history.svg" readonly property bool isRichText: false } QtObject { id: deviceCountObject readonly property string title: qsTr("Active Connections") readonly property string contentKey: "connectedDevices" readonly property string objectImageSource: "qrc:/images/controls/monitor.svg" readonly property bool isRichText: false } property var processedServer property bool isSubscriptionExpired: false property bool isSubscriptionExpiringSoon: false property bool isSubscriptionRenewalAvailable: false property bool isInAppPurchase: false function updateSubscriptionState() { root.isSubscriptionExpired = ApiAccountInfoModel.data("isSubscriptionExpired") root.isSubscriptionExpiringSoon = ApiAccountInfoModel.data("isSubscriptionExpiringSoon") root.isSubscriptionRenewalAvailable = ApiAccountInfoModel.data("isSubscriptionRenewalAvailable") root.isInAppPurchase = ApiAccountInfoModel.data("isInAppPurchase") } Component.onCompleted: { root.updateSubscriptionState() } Connections { target: ApiAccountInfoModel function onModelReset() { root.updateSubscriptionState() } } Connections { target: ServersUiController function onProcessedServerIdChanged() { root.processedServer = proxyServersModel.get(0) } } Connections { target: ServersModel function onModelReset() { root.processedServer = proxyServersModel.get(0) } } SortFilterProxyModel { id: proxyServersModel objectName: "proxyServersModel" sourceModel: ServersModel filters: [ ValueFilter { roleName: "serverId" value: ServersUiController.processedServerId } ] Component.onCompleted: { root.processedServer = proxyServersModel.get(0) } } ListViewType { id: listView anchors.fill: parent model: labelsModel header: ColumnLayout { width: listView.width spacing: 4 BackButtonType { id: backButton objectName: "backButton" Layout.topMargin: 20 + PageController.safeAreaTopMargin } HeaderTypeWithButton { id: headerContent objectName: "headerContent" Layout.fillWidth: true Layout.leftMargin: 16 Layout.rightMargin: 16 Layout.bottomMargin: root.isSubscriptionExpired || root.isSubscriptionExpiringSoon ? 0 : 10 actionButtonImage: "qrc:/images/controls/edit-3.svg" headerText: root.processedServer != null ? root.processedServer.name : "" actionButtonFunction: function() { serverNameEditDrawer.openTriggered() } } ParagraphTextType { visible: root.isSubscriptionExpired || root.isSubscriptionExpiringSoon Layout.fillWidth: true Layout.leftMargin: 16 Layout.rightMargin: 16 Layout.topMargin: 12 text: root.isSubscriptionExpired ? qsTr("Subscription expired") : qsTr("Subscription expiring soon") color: root.isSubscriptionExpired ? AmneziaStyle.color.vibrantRed : AmneziaStyle.color.goldenApricot } ParagraphTextType { visible: ApiAccountInfoModel.data("serviceDescription") !== "" Layout.fillWidth: true Layout.leftMargin: 16 Layout.rightMargin: 16 Layout.topMargin: 16 Layout.bottomMargin: root.isSubscriptionExpired || root.isSubscriptionExpiringSoon ? 0 : 10 text: ApiAccountInfoModel.data("serviceDescription") color: AmneziaStyle.color.mutedGray } BasicButtonType { visible: (root.isSubscriptionExpired || root.isSubscriptionExpiringSoon) && root.isSubscriptionRenewalAvailable && !root.isInAppPurchase Layout.fillWidth: true Layout.leftMargin: 16 Layout.rightMargin: 16 Layout.topMargin: 8 Layout.bottomMargin: 8 text: qsTr("Renew subscription") defaultColor: AmneziaStyle.color.paleGray hoveredColor: AmneziaStyle.color.lightGray pressedColor: AmneziaStyle.color.mutedGray textColor: AmneziaStyle.color.midnightBlack clickedFunc: function() { SubscriptionUiController.getRenewalLink(ServersUiController.processedServerId) } } } delegate: ColumnLayout { width: listView.width spacing: 0 Connections { target: ApiAccountInfoModel function onModelReset() { delegateItem.rightText = ApiAccountInfoModel.data(contentKey) } } LabelWithImageType { id: delegateItem Layout.fillWidth: true Layout.margins: 16 imageSource: objectImageSource leftText: title rightText: ApiAccountInfoModel.data(contentKey) rightTextFormat: isRichText ? Text.RichText : Text.PlainText visible: rightText !== "" } } footer: ColumnLayout { id: footer width: listView.width spacing: 0 readonly property bool isVisibleForAmneziaFree: ApiAccountInfoModel.data("isComponentVisible") BasicButtonType { visible: !root.isSubscriptionExpired && !root.isSubscriptionExpiringSoon && root.isSubscriptionRenewalAvailable && !root.isInAppPurchase Layout.alignment: Qt.AlignHCenter Layout.topMargin: 16 Layout.bottomMargin: 16 implicitHeight: 25 defaultColor: AmneziaStyle.color.transparent hoveredColor: AmneziaStyle.color.translucentWhite pressedColor: AmneziaStyle.color.sheerWhite textColor: AmneziaStyle.color.goldenApricot leftImageSource: "qrc:/images/controls/refresh-cw.svg" leftImageColor: AmneziaStyle.color.goldenApricot text: qsTr("Renew subscription") clickedFunc: function() { SubscriptionUiController.getRenewalLink(ServersUiController.processedServerId) } } DividerType { visible: !root.isSubscriptionExpired && !root.isSubscriptionExpiringSoon && root.isSubscriptionRenewalAvailable && !root.isInAppPurchase } SwitcherType { id: switcher readonly property bool isVlessProtocol: SubscriptionUiController.isVlessProtocol(ServersUiController.processedServerId) readonly property bool isProtocolSwitchBlocked: ServersUiController.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected Layout.fillWidth: true Layout.topMargin: 24 Layout.rightMargin: 16 Layout.leftMargin: 16 Layout.bottomMargin: 24 visible: ApiAccountInfoModel.data("isProtocolSelectionSupported") enabled: !switcher.isProtocolSwitchBlocked text: qsTr("Use VLESS protocol") checked: switcher.isVlessProtocol onToggled: function() { if (ServersUiController.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { PageController.showNotificationMessage(qsTr("Cannot change protocol during active connection")) } else { PageController.showBusyIndicator(true) SubscriptionUiController.setCurrentProtocol(ServersUiController.processedServerId, switcher.isVlessProtocol ? "awg" : "vless") SubscriptionUiController.updateServiceFromGateway(ServersUiController.processedServerId, "", "", true) PageController.showBusyIndicator(false) } } } DividerType { visible: footer.isVisibleForAmneziaFree } WarningType { id: warning Layout.topMargin: 24 Layout.rightMargin: 16 Layout.leftMargin: 16 Layout.fillWidth: true backGroundColor: AmneziaStyle.color.translucentRichBrown textString: qsTr("Configurations have been updated for some countries. Download and install the updated configuration files") iconPath: "qrc:/images/controls/alert-circle.svg" visible: { for (let i = 0; i < ApiCountryModel.count; ++i) { if (ApiCountryModel.get(i).isWorkerExpired) return true; } return false; } } LabelWithButtonType { id: vpnKey Layout.fillWidth: true Layout.topMargin: warning.visible ? 16 : 0 visible: footer.isVisibleForAmneziaFree text: qsTr("Subscription Key") rightImageSource: "qrc:/images/controls/chevron-right.svg" clickedFunction: function() { PageController.goToPage(PageEnum.PageSettingsApiSubscriptionKey) PageController.showBusyIndicator(true) SubscriptionUiController.prepareVpnKeyExport(ServersUiController.processedServerId) PageController.showBusyIndicator(false) } } DividerType { visible: footer.isVisibleForAmneziaFree } LabelWithButtonType { Layout.fillWidth: true visible: footer.isVisibleForAmneziaFree text: qsTr("Configuration Files") descriptionText: qsTr("Manage configuration files") rightImageSource: "qrc:/images/controls/chevron-right.svg" clickedFunction: function() { SubscriptionUiController.updateApiCountryModel() PageController.goToPage(PageEnum.PageSettingsApiNativeConfigs) } } DividerType { visible: footer.isVisibleForAmneziaFree } LabelWithButtonType { Layout.fillWidth: true visible: footer.isVisibleForAmneziaFree text: qsTr("Active Devices") descriptionText: qsTr("Manage currently connected devices") rightImageSource: "qrc:/images/controls/chevron-right.svg" clickedFunction: function() { SubscriptionUiController.updateApiDevicesModel() PageController.goToPage(PageEnum.PageSettingsApiDevices) } } DividerType { visible: footer.isVisibleForAmneziaFree } LabelWithButtonType { Layout.fillWidth: true Layout.topMargin: footer.isVisibleForAmneziaFree ? 0 : 32 text: qsTr("Support") rightImageSource: "qrc:/images/controls/chevron-right.svg" clickedFunction: function() { PageController.goToPage(PageEnum.PageSettingsApiSupport) } } DividerType {} LabelWithButtonType { Layout.fillWidth: true visible: footer.isVisibleForAmneziaFree text: qsTr("How to connect on another device") rightImageSource: "qrc:/images/controls/chevron-right.svg" clickedFunction: function() { PageController.goToPage(PageEnum.PageSettingsApiInstructions) } } DividerType { visible: footer.isVisibleForAmneziaFree } BasicButtonType { id: resetButton Layout.alignment: Qt.AlignHCenter Layout.topMargin: 24 Layout.bottomMargin: 16 Layout.leftMargin: 8 implicitHeight: 32 defaultColor: "transparent" hoveredColor: AmneziaStyle.color.translucentWhite pressedColor: AmneziaStyle.color.sheerWhite textColor: AmneziaStyle.color.vibrantRed text: qsTr("Reload API config") clickedFunc: function() { var headerText = qsTr("Reload API config?") var yesButtonText = qsTr("Continue") var noButtonText = qsTr("Cancel") var yesButtonFunction = function() { if (ServersUiController.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { PageController.showNotificationMessage(qsTr("Cannot reload API config during active connection")) } else { PageController.showBusyIndicator(true) SubscriptionUiController.updateServiceFromGateway(ServersUiController.processedServerId, "", "", true) PageController.showBusyIndicator(false) } } var noButtonFunction = function() { } showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) } } BasicButtonType { id: revokeButton Layout.alignment: Qt.AlignHCenter Layout.bottomMargin: 16 Layout.leftMargin: 8 implicitHeight: 32 visible: footer.isVisibleForAmneziaFree defaultColor: "transparent" hoveredColor: AmneziaStyle.color.translucentWhite pressedColor: AmneziaStyle.color.sheerWhite textColor: AmneziaStyle.color.vibrantRed text: qsTr("Unlink this device") clickedFunc: function() { var headerText = qsTr("Are you sure you want to unlink this device?") var descriptionText = qsTr("This will unlink the device from your subscription. You can reconnect it anytime by pressing \"Reload API config\" in subscription settings on device.") var yesButtonText = qsTr("Continue") var noButtonText = qsTr("Cancel") var yesButtonFunction = function() { if (ServersUiController.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { PageController.showNotificationMessage(qsTr("Cannot unlink device during active connection")) } else { PageController.showBusyIndicator(true) if (SubscriptionUiController.deactivateDevice(ServersUiController.processedServerId)) { SubscriptionUiController.getAccountInfo(ServersUiController.processedServerId, true) } PageController.showBusyIndicator(false) } } var noButtonFunction = function() { } showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) } } BasicButtonType { id: removeButton Layout.alignment: Qt.AlignHCenter Layout.bottomMargin: 16 Layout.leftMargin: 8 implicitHeight: 32 defaultColor: "transparent" hoveredColor: AmneziaStyle.color.translucentWhite pressedColor: AmneziaStyle.color.sheerWhite textColor: AmneziaStyle.color.vibrantRed text: qsTr("Remove from application") clickedFunc: function() { var headerText = qsTr("Remove from application?") var yesButtonText = qsTr("Continue") var noButtonText = qsTr("Cancel") var yesButtonFunction = function() { if (ServersUiController.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { PageController.showNotificationMessage(qsTr("Cannot remove server during active connection")) } else { PageController.showBusyIndicator(true) SubscriptionUiController.removeServer(ServersUiController.processedServerId) PageController.showBusyIndicator(false) } } var noButtonFunction = function() { } showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) } } } } RenameServerDrawer { id: serverNameEditDrawer anchors.fill: parent expandedHeight: parent.height * 0.35 serverNameText: root.processedServer != null ? root.processedServer.name : "" } }