New start page and AmneziaFree support (#865)

New start page and AmneziaFree support
This commit is contained in:
Nethius 2024-08-20 16:54:05 +07:00 committed by GitHub
parent 01413e5a4c
commit 843156cf1b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
443 changed files with 11759 additions and 2758 deletions

View file

@ -5,6 +5,7 @@ import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -0,0 +1,94 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
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
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
BackButtonType {
id: backButton
// KeyNavigation.tab: removeButton
}
}
FlickableType {
id: fl
anchors.top: backButtonLayout.bottom
anchors.bottom: parent.bottom
contentHeight: content.implicitHeight
ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
HeaderType {
id: header
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
headerText: "Dev menu"
}
TextFieldWithHeaderType {
id: passwordTextField
Layout.fillWidth: true
Layout.topMargin: 16
Layout.rightMargin: 16
Layout.leftMargin: 16
parentFlickable: fl
headerText: qsTr("Gateway endpoint")
textFieldText: SettingsController.gatewayEndpoint
buttonImageSource: textFieldText !== "" ? "qrc:/images/controls/refresh-cw.svg" : ""
clickedFunc: function() {
SettingsController.resetGatewayEndpoint()
}
textField.onEditingFinished: {
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
if (textFieldText !== SettingsController.gatewayEndpoint) {
SettingsController.gatewayEndpoint = textFieldText
}
}
// KeyNavigation.tab: saveButton
}
}
}
}

View file

@ -57,10 +57,10 @@ PageType {
implicitHeight: 36
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.grey
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.mutedGray
borderWidth: 0
visible: isLoggingEnabled ? true : false
@ -94,10 +94,10 @@ PageType {
implicitHeight: 36
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.grey
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.mutedGray
leftImageColor: AmneziaStyle.color.transparent
borderWidth: 0
@ -106,7 +106,7 @@ PageType {
buttonTextLabel.font.weight: 500
property bool isSplitTunnelingEnabled: SitesModel.isTunnelingEnabled || AppSplitTunnelingModel.isTunnelingEnabled ||
(ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi"))
ServersModel.isDefaultServerDefaultContainerHasSplitTunneling
text: isSplitTunnelingEnabled ? qsTr("Split tunneling enabled") : qsTr("Split tunneling disabled")
@ -243,7 +243,7 @@ PageType {
hoverEnabled: false
image: "qrc:/images/controls/chevron-down.svg"
imageColor: AmneziaStyle.color.white
imageColor: AmneziaStyle.color.paleGray
icon.width: 18
icon.height: 18
@ -265,11 +265,21 @@ PageType {
}
}
LabelTextType {
id: collapsedServerMenuDescription
Layout.bottomMargin: drawer.isCollapsed ? 44 : ServersModel.isDefaultServerFromApi ? 89 : 44
RowLayout {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
text: drawer.isCollapsed ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
Layout.bottomMargin: drawer.isCollapsed ? 44 : ServersModel.isDefaultServerFromApi ? 89 : 44
spacing: 0
Image {
Layout.rightMargin: 8
visible: source !== ""
source: ServersModel.defaultServerImagePathCollapsed
}
LabelTextType {
id: collapsedServerMenuDescription
text: drawer.isCollapsed ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
}
}
}
@ -304,8 +314,8 @@ PageType {
DropDownType {
id: containersDropDown
rootButtonImageColor: AmneziaStyle.color.black
rootButtonBackgroundColor: AmneziaStyle.color.white
rootButtonImageColor: AmneziaStyle.color.midnightBlack
rootButtonBackgroundColor: AmneziaStyle.color.paleGray
rootButtonBackgroundHoveredColor: Qt.rgba(215, 216, 219, 0.8)
rootButtonBackgroundPressedColor: Qt.rgba(215, 216, 219, 0.65)
rootButtonHoveredBorderColor: AmneziaStyle.color.transparent
@ -314,7 +324,7 @@ PageType {
rootButtonTextBottomMargin: 8
text: ServersModel.defaultServerDefaultContainerName
textColor: AmneziaStyle.color.black
textColor: AmneziaStyle.color.midnightBlack
headerText: qsTr("VPN protocol")
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
@ -505,7 +515,7 @@ PageType {
ImageButtonType {
id: serverInfoButton
image: "qrc:/images/controls/settings.svg"
imageColor: AmneziaStyle.color.white
imageColor: AmneziaStyle.color.paleGray
implicitWidth: 56
implicitHeight: 56

View file

@ -5,6 +5,7 @@ import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -5,6 +5,7 @@ import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -295,7 +295,7 @@ PageType {
Layout.fillWidth: true
Layout.topMargin: 32
Layout.preferredHeight: checkboxLayout.implicitHeight
color: AmneziaStyle.color.blackLight
color: AmneziaStyle.color.onyxBlack
radius: 16
Connections {

View file

@ -192,9 +192,9 @@ PageType {
leftPadding: 0
height: 24
color: AmneziaStyle.color.white
selectionColor: AmneziaStyle.color.brown
selectedTextColor: AmneziaStyle.color.white
color: AmneziaStyle.color.paleGray
selectionColor: AmneziaStyle.color.richBrown
selectedTextColor: AmneziaStyle.color.paleGray
font.pixelSize: 16
font.weight: Font.Medium
@ -224,7 +224,7 @@ PageType {
visible: ServersModel.isProcessedServerHasWriteAccess()
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
textColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunction: function() {

View file

@ -5,6 +5,7 @@ import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -5,6 +5,7 @@ import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -6,6 +6,7 @@ import SortFilterProxyModel 0.2
import PageEnum 1.0
import ContainerEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -70,7 +70,7 @@ PageType {
width: parent.width
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
textColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
Keys.onTabPressed: root.lastItemTabClicked()

View file

@ -115,7 +115,7 @@ PageType {
descriptionOnTop: true
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.white
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
@ -139,7 +139,7 @@ PageType {
KeyNavigation.tab: usernameLabel.rightButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.white
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
@ -163,7 +163,7 @@ PageType {
KeyNavigation.tab: passwordLabel.eyeButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.white
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
@ -194,7 +194,7 @@ PageType {
}
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.white
rightImageColor: AmneziaStyle.color.paleGray
buttonImageSource: hideDescription ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg"
@ -218,10 +218,10 @@ PageType {
Layout.rightMargin: 16
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.white
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.paleGray
borderWidth: 1
parentFlickable: fl
@ -282,10 +282,10 @@ PageType {
implicitHeight: 32
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.orange
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.goldenApricot
text: qsTr("Detailed instructions")

View file

@ -6,6 +6,7 @@ import SortFilterProxyModel 0.2
import PageEnum 1.0
import ContainerProps 1.0
import Style 1.0
import "./"
import "../Controls2"
@ -106,7 +107,7 @@ PageType {
descriptionOnTop: true
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: "#D7D8DB"
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
@ -130,7 +131,7 @@ PageType {
KeyNavigation.tab: usernameLabel.rightButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: "#D7D8DB"
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
@ -154,7 +155,7 @@ PageType {
KeyNavigation.tab: passwordLabel.eyeButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: "#D7D8DB"
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
@ -179,7 +180,7 @@ PageType {
rightButton.KeyNavigation.tab: changeSettingsButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: "#D7D8DB"
rightImageColor: AmneziaStyle.color.paleGray
buttonImageSource: hideDescription ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg"

View file

@ -83,10 +83,10 @@ PageType {
}
descriptionOnTop: true
textColor: AmneziaStyle.color.orange
textColor: AmneziaStyle.color.goldenApricot
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.white
rightImageColor: AmneziaStyle.color.paleGray
Keys.onTabPressed: lastItemTabClicked(focusItem)

View file

@ -4,6 +4,7 @@ import QtQuick.Layouts
import QtQuick.Dialogs
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
@ -128,6 +129,26 @@ PageType {
DividerType {}
LabelWithButtonType {
id: devConsole
visible: SettingsController.isDevModeEnabled
Layout.fillWidth: true
text: qsTr("Dev console")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/bug.svg"
// Keys.onTabPressed: lastItemTabClicked(header)
clickedFunction: function() {
PageController.goToPage(PageEnum.PageDevMenu)
}
}
DividerType {
visible: SettingsController.isDevModeEnabled
}
LabelWithButtonType {
id: close
visible: GC.isDesktop()

View file

@ -85,7 +85,7 @@ PageType {
font.pixelSize: 14
text: qsTr("Amnezia is a free and open-source application. You can support the developers if you like it.")
color: AmneziaStyle.color.white
color: AmneziaStyle.color.paleGray
}
ParagraphTextType {
@ -163,7 +163,7 @@ PageType {
parentFlickable: fl
clickedFunction: function() {
Qt.openUrlExternally(qsTr("https://amnezia.org"))
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
}
}
@ -177,7 +177,19 @@ PageType {
horizontalAlignment: Text.AlignHCenter
text: qsTr("Software version: %1").arg(SettingsController.getAppVersion())
color: AmneziaStyle.color.grey
color: AmneziaStyle.color.mutedGray
MouseArea {
property int clickCount: 0
anchors.fill: parent
onClicked: {
if (clickCount > 10) {
SettingsController.enableDevMode()
} else {
clickCount++
}
}
}
}
BasicButtonType {
@ -188,10 +200,10 @@ PageType {
implicitHeight: 32
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.orange
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.goldenApricot
text: qsTr("Check for updates")
@ -211,10 +223,10 @@ PageType {
implicitHeight: 25
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.orange
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.goldenApricot
text: qsTr("Privacy Policy")
@ -222,7 +234,7 @@ PageType {
parentFlickable: fl
clickedFunc: function() {
Qt.openUrlExternally("https://amnezia.org/en/policy")
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl() + "/policy")
}
}
}

View file

@ -0,0 +1,103 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
import "../Components"
PageType {
id: root
ListView {
id: menuContent
property var selectedText
width: parent.width
height: menuContent.contentItem.height
clip: true
interactive: false
model: ApiCountryModel
ButtonGroup {
id: containersRadioButtonGroup
}
delegate: Item {
implicitWidth: parent.width
implicitHeight: content.implicitHeight
ColumnLayout {
id: content
anchors.fill: parent
RowLayout {
VerticalRadioButton {
id: containerRadioButton
Layout.fillWidth: true
Layout.leftMargin: 16
text: countryName
ButtonGroup.group: containersRadioButtonGroup
imageSource: "qrc:/images/controls/download.svg"
checked: index === ApiCountryModel.currentIndex
onClicked: {
if (index !== ApiCountryModel.currentIndex) {
PageController.showBusyIndicator(true)
var prevIndex = ApiCountryModel.currentIndex
ApiCountryModel.currentIndex = index
if (!InstallController.updateServiceFromApi(ServersModel.defaultIndex, countryCode, countryName)) {
ApiCountryModel.currentIndex = prevIndex
}
}
}
MouseArea {
anchors.fill: containerRadioButton
cursorShape: Qt.PointingHandCursor
enabled: false
}
Keys.onEnterPressed: {
if (checkable) {
checked = true
}
containerRadioButton.clicked()
}
Keys.onReturnPressed: {
if (checkable) {
checked = true
}
containerRadioButton.clicked()
}
}
Image {
Layout.rightMargin: 32
Layout.alignment: Qt.AlignRight
source: "qrc:/countriesFlags/images/flagKit/" + countryCode + ".svg"
}
}
DividerType {
Layout.fillWidth: true
}
}
}
}
}

View file

@ -0,0 +1,208 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
FlickableType {
id: fl
anchors.top: parent.top
anchors.bottom: parent.bottom
contentHeight: content.height
ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 0
Item {
id: focusItem
// KeyNavigation.tab: backButton
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/map-pin.svg"
leftText: qsTr("For the region")
rightText: ApiServicesModel.getSelectedServiceData("region")
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/tag.svg"
leftText: qsTr("Price")
rightText: ApiServicesModel.getSelectedServiceData("price")
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/history.svg"
leftText: qsTr("Work period")
rightText: ApiServicesModel.getSelectedServiceData("workPeriod")
visible: rightText !== ""
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/gauge.svg"
leftText: qsTr("Speed")
rightText: ApiServicesModel.getSelectedServiceData("speed")
}
ParagraphTextType {
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
onLinkActivated: function(link) {
Qt.openUrlExternally(link)
}
textFormat: Text.RichText
text: {
var text = ApiServicesModel.getSelectedServiceData("features")
if (text === undefined) {
return ""
}
return text.replace("%1", LanguageModel.getCurrentSiteUrl())
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
LabelWithButtonType {
id: supportUuid
Layout.fillWidth: true
text: qsTr("Support tag")
descriptionText: SettingsController.getInstallationUuid()
descriptionOnTop: true
// parentFlickable: fl
// KeyNavigation.tab: passwordLabel.eyeButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
PageController.showNotificationMessage(qsTr("Copied"))
if (!GC.isMobile()) {
this.rightButton.forceActiveFocus()
}
}
}
BasicButtonType {
id: resetButton
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 24
Layout.bottomMargin: 16
Layout.leftMargin: 8
implicitHeight: 32
defaultColor: "transparent"
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
pressedColor: Qt.rgba(1, 1, 1, 0.12)
textColor: AmneziaStyle.color.vibrantRed
text: qsTr("Reload API config")
// Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunc: function() {
var headerText = qsTr("Reload API config?")
var yesButtonText = qsTr("Continue")
var noButtonText = qsTr("Cancel")
var yesButtonFunction = function() {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
PageController.showNotificationMessage(qsTr("Cannot reload API config during active connection"))
} else {
PageController.showBusyIndicator(true)
InstallController.updateServiceFromApi(ServersModel.processedIndex, "", "", true)
PageController.showBusyIndicator(false)
}
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
removeButton.forceActiveFocus()
}
}
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
}
BasicButtonType {
id: removeButton
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: 16
Layout.leftMargin: 8
implicitHeight: 32
defaultColor: "transparent"
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
pressedColor: Qt.rgba(1, 1, 1, 0.12)
textColor: AmneziaStyle.color.vibrantRed
text: qsTr("Remove from application")
// Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunc: function() {
var headerText = qsTr("Remove from application?")
var yesButtonText = qsTr("Continue")
var noButtonText = qsTr("Cancel")
var yesButtonFunction = function() {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
PageController.showNotificationMessage(qsTr("Cannot remove server during active connection"))
} else {
PageController.showBusyIndicator(true)
InstallController.removeProcessedServer()
PageController.showBusyIndicator(false)
}
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
removeButton.forceActiveFocus()
}
}
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
}
}
}
}

View file

@ -215,7 +215,7 @@ PageType {
text: appPath
rightImageSource: "qrc:/images/controls/trash.svg"
rightImageColor: AmneziaStyle.color.white
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
var headerText = qsTr("Remove ") + appPath + "?"
@ -242,7 +242,7 @@ PageType {
Rectangle {
anchors.fill: addAppButton
anchors.bottomMargin: -24
color: AmneziaStyle.color.black
color: AmneziaStyle.color.midnightBlack
opacity: 0.8
}

View file

@ -224,7 +224,7 @@ PageType {
text: qsTr("Reset settings and remove all data from the application")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
textColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
Keys.onTabPressed: lastItemTabClicked()
parentFlickable: fl
@ -241,7 +241,7 @@ PageType {
} else
{
SettingsController.clearSettings()
PageController.replaceStartPage()
PageController.goToPageHome()
}
if (!GC.isMobile()) {

View file

@ -28,7 +28,6 @@ PageType {
function onRestoreBackupFinished() {
PageController.showNotificationMessage(qsTr("Settings restored from backup file"))
//goToStartPage()
PageController.goToPageHome()
}
@ -122,10 +121,10 @@ PageType {
Layout.topMargin: -8
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.white
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.paleGray
borderWidth: 1
text: qsTr("Restore from backup")

View file

@ -3,6 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -38,7 +38,7 @@ PageType {
anchors.bottom: parent.bottom
contentHeight: content.height
property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
property var isServerFromApi: ServersModel.isServerFromApi(ServersModel.defaultIndex)
enabled: !isServerFromApi
@ -103,10 +103,10 @@ PageType {
Layout.fillWidth: true
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.white
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.paleGray
borderWidth: 1
text: qsTr("Restore default")

View file

@ -115,7 +115,7 @@ disabled after 14 days, and all log files will be deleted.")
Layout.fillWidth: true
text: qsTr("Open folder with logs")
color: AmneziaStyle.color.white
color: AmneziaStyle.color.paleGray
}
}
@ -160,7 +160,7 @@ disabled after 14 days, and all log files will be deleted.")
Layout.fillWidth: true
text: qsTr("Save logs to file")
color: AmneziaStyle.color.white
color: AmneziaStyle.color.paleGray
}
}
@ -209,7 +209,7 @@ disabled after 14 days, and all log files will be deleted.")
Layout.fillWidth: true
text: qsTr("Clear logs")
color: AmneziaStyle.color.white
color: AmneziaStyle.color.paleGray
}
}
}

View file

@ -38,7 +38,7 @@ PageType {
function onRemoveProcessedServerFinished(finishedMessage) {
if (!ServersModel.getServersCount()) {
PageController.replaceStartPage()
PageController.goToPageHome()
} else {
PageController.goToStartPage()
PageController.goToPage(PageEnum.PageSettingsServersList)
@ -119,7 +119,7 @@ PageType {
Layout.fillWidth: true
text: qsTr("Reboot server")
textColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
KeyNavigation.tab: labelWithButton3
@ -160,7 +160,7 @@ PageType {
Layout.fillWidth: true
text: qsTr("Remove server from application")
textColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
Keys.onTabPressed: {
if (content.isServerWithWriteAccess) {
@ -208,7 +208,7 @@ PageType {
Layout.fillWidth: true
text: qsTr("Clear server from Amnezia software")
textColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
Keys.onTabPressed: labelWithButton5.visible ?
labelWithButton5.forceActiveFocus() :
@ -247,11 +247,11 @@ PageType {
LabelWithButtonType {
id: labelWithButton5
visible: ServersModel.getProcessedServerData("isServerFromApi")
visible: ServersModel.getProcessedServerData("isServerFromTelegramApi")
Layout.fillWidth: true
text: qsTr("Reset API config")
textColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
Keys.onTabPressed: root.lastItemTabClickedSignal()
@ -285,7 +285,7 @@ PageType {
}
DividerType {
visible: ServersModel.getProcessedServerData("isServerFromApi")
visible: ServersModel.getProcessedServerData("isServerFromTelegramApi")
}
}
}

View file

@ -19,13 +19,19 @@ import "../Components"
PageType {
id: root
property int pageSettingsServerProtocols: 0
property int pageSettingsServerServices: 1
property int pageSettingsServerData: 2
property int pageSettingsApiServerInfo: 3
property int pageSettingsApiLanguageList: 4
defaultActiveFocusItem: focusItem
Connections {
target: PageController
function onGoToPageSettingsServerServices() {
tabBar.currentIndex = 1
tabBar.currentIndex = root.pageSettingsServerServices
}
}
@ -70,6 +76,15 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: headerContent.actionButton
backButtonFunction: function() {
if (nestedStackView.currentIndex === root.pageSettingsApiServerInfo &&
ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
nestedStackView.currentIndex = root.pageSettingsApiLanguageList
} else {
PageController.closePage()
}
}
}
HeaderType {
@ -78,11 +93,15 @@ PageType {
Layout.leftMargin: 16
Layout.rightMargin: 16
actionButtonImage: "qrc:/images/controls/edit-3.svg"
actionButtonImage: nestedStackView.currentIndex === root.pageSettingsApiLanguageList ? "qrc:/images/controls/settings.svg" : "qrc:/images/controls/edit-3.svg"
headerText: name
descriptionText: {
if (ServersModel.isProcessedServerHasWriteAccess()) {
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
return ApiServicesModel.getSelectedServiceData("serviceDescription")
} else if (ServersModel.getProcessedServerData("isServerFromTelegramApi")) {
return serverDescription
} else if (ServersModel.isProcessedServerHasWriteAccess()) {
return credentialsLogin + " · " + hostName
} else {
return hostName
@ -92,7 +111,11 @@ PageType {
KeyNavigation.tab: tabBar
actionButtonFunction: function() {
serverNameEditDrawer.open()
if (nestedStackView.currentIndex === root.pageSettingsApiLanguageList) {
nestedStackView.currentIndex = root.pageSettingsApiServerInfo
} else {
serverNameEditDrawer.open()
}
}
}
@ -172,13 +195,16 @@ PageType {
Layout.fillWidth: true
currentIndex: (ServersModel.getProcessedServerData("isServerFromApi")
&& !ServersModel.getProcessedServerData("hasInstalledContainers")) ? 2 : 0
currentIndex: (ServersModel.getProcessedServerData("isServerFromTelegramApi")
&& !ServersModel.getProcessedServerData("hasInstalledContainers")) ?
root.pageSettingsServerData : root.pageSettingsServerProtocols
background: Rectangle {
color: AmneziaStyle.color.transparent
}
visible: !ServersModel.getProcessedServerData("isServerFromGatewayApi")
activeFocusOnTab: true
onFocusChanged: {
if (activeFocus) {
@ -190,45 +216,53 @@ PageType {
id: protocolsTab
visible: protocolsPage.installedProtocolsCount
width: protocolsPage.installedProtocolsCount ? undefined : 0
isSelected: tabBar.currentIndex === 0
isSelected: tabBar.currentIndex === root.pageSettingsServerProtocols
text: qsTr("Protocols")
KeyNavigation.tab: servicesTab
Keys.onReturnPressed: tabBar.currentIndex = 0
Keys.onEnterPressed: tabBar.currentIndex = 0
Keys.onReturnPressed: tabBar.currentIndex = root.pageSettingsServerProtocols
Keys.onEnterPressed: tabBar.currentIndex = root.pageSettingsServerProtocols
}
TabButtonType {
id: servicesTab
visible: servicesPage.installedServicesCount
width: servicesPage.installedServicesCount ? undefined : 0
isSelected: tabBar.currentIndex === 1
isSelected: tabBar.currentIndex === root.pageSettingsServerServices
text: qsTr("Services")
KeyNavigation.tab: dataTab
Keys.onReturnPressed: tabBar.currentIndex = 1
Keys.onEnterPressed: tabBar.currentIndex = 1
Keys.onReturnPressed: tabBar.currentIndex = root.pageSettingsServerServices
Keys.onEnterPressed: tabBar.currentIndex = root.pageSettingsServerServices
}
TabButtonType {
id: dataTab
isSelected: tabBar.currentIndex === 2
isSelected: tabBar.currentIndex === root.pageSettingsServerData
text: qsTr("Management")
Keys.onReturnPressed: tabBar.currentIndex = 2
Keys.onEnterPressed: tabBar.currentIndex = 2
KeyNavigation.tab: stackView.currentIndex === 0 ?
protocolsPage :
stackView.currentIndex === 1 ?
servicesPage :
dataPage
Keys.onReturnPressed: tabBar.currentIndex = root.pageSettingsServerData
Keys.onEnterPressed: tabBar.currentIndex = root.pageSettingsServerData
Keys.onTabPressed: function() {
if (nestedStackView.currentIndex === root.pageSettingsServerProtocols) {
return protocolsPage
} else if (nestedStackView.currentIndex === root.pageSettingsServerProtocols) {
return servicesPage
} else {
return dataPage
}
}
}
}
StackLayout {
id: stackView
id: nestedStackView
Layout.preferredWidth: root.width
Layout.preferredHeight: root.height - tabBar.implicitHeight - header.implicitHeight
currentIndex: tabBar.currentIndex
currentIndex: ServersModel.getProcessedServerData("isServerFromGatewayApi") ?
(ServersModel.getProcessedServerData("isCountrySelectionAvailable") ?
root.pageSettingsApiLanguageList : root.pageSettingsApiServerInfo) : tabBar.currentIndex
PageSettingsServerProtocols {
id: protocolsPage
@ -236,18 +270,34 @@ PageType {
onLastItemTabClickedSignal: lastItemTabClicked(focusItem)
}
PageSettingsServerServices {
id: servicesPage
stackView: root.stackView
onLastItemTabClickedSignal: lastItemTabClicked(focusItem)
}
PageSettingsServerData {
id: dataPage
stackView: root.stackView
onLastItemTabClickedSignal: lastItemTabClicked(focusItem)
}
PageSettingsApiServerInfo {
id: apiInfoPage
stackView: root.stackView
// onLastItemTabClickedSignal: lastItemTabClicked(focusItem)
}
PageSettingsApiLanguageList {
id: apiLanguageListPage
stackView: root.stackView
// onLastItemTabClickedSignal: lastItemTabClicked(focusItem)
}
}
}

View file

@ -184,7 +184,7 @@ PageType {
Keys.onTabPressed: lastItemTabClicked(focusItem)
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
textColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
clickedFunction: function() {
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())

View file

@ -8,6 +8,7 @@ import PageEnum 1.0
import ProtocolEnum 1.0
import ContainerProps 1.0
import ContainersModelFilters 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -8,6 +8,7 @@ import PageEnum 1.0
import ProtocolEnum 1.0
import ContainerProps 1.0
import ContainersModelFilters 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -7,6 +7,7 @@ import SortFilterProxyModel 0.2
import PageEnum 1.0
import ProtocolEnum 1.0
import ContainerProps 1.0
import Style 1.0
import "./"
import "../Controls2"
@ -119,7 +120,11 @@ PageType {
servicesNameString += servicesName[i] + " · "
}
return servicesNameString + hostName
if (ServersModel.isServerFromApi(index)) {
return servicesNameString + serverDescription
} else {
return servicesNameString + hostName
}
}
rightImageSource: "qrc:/images/controls/chevron-right.svg"

View file

@ -21,7 +21,7 @@ import "../Components"
PageType {
id: root
property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
property var isServerFromTelegramApi: ServersModel.getDefaultServerData("isServerFromTelegramApi")
defaultActiveFocusItem: searchField.textField
@ -36,7 +36,7 @@ PageType {
if (ConnectionController.isConnected) {
PageController.showNotificationMessage(qsTr("Cannot change split tunneling settings during active connection"))
root.pageEnabled = false
} else if (ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && isServerFromApi) {
} else if (ServersModel.isDefaultServerDefaultContainerHasSplitTunneling) {
PageController.showNotificationMessage(qsTr("Default server does not support split tunneling function"))
root.pageEnabled = false
} else {
@ -266,7 +266,7 @@ PageType {
text: url
descriptionText: ip
rightImageSource: "qrc:/images/controls/trash.svg"
rightImageColor: AmneziaStyle.color.white
rightImageColor: AmneziaStyle.color.paleGray
clickedFunction: function() {
var headerText = qsTr("Remove ") + url + "?"
@ -300,7 +300,7 @@ PageType {
Rectangle {
anchors.fill: addSiteButton
anchors.bottomMargin: -24
color: AmneziaStyle.color.black
color: AmneziaStyle.color.midnightBlack
opacity: 0.8
}
@ -341,7 +341,7 @@ PageType {
implicitHeight: 56
image: "qrc:/images/controls/more-vertical.svg"
imageColor: AmneziaStyle.color.white
imageColor: AmneziaStyle.color.paleGray
onClicked: function () {
moreActionsDrawer.open()

View file

@ -0,0 +1,154 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
FlickableType {
id: fl
anchors.top: parent.top
anchors.bottom: parent.bottom
contentHeight: content.height + continueButton.implicitHeight + continueButton.anchors.bottomMargin + continueButton.anchors.topMargin
ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 0
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
Layout.topMargin: 20
// KeyNavigation.tab: fileButton.rightButton
}
HeaderType {
Layout.fillWidth: true
Layout.topMargin: 8
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 32
headerText: ApiServicesModel.getSelectedServiceData("name")
descriptionText: ApiServicesModel.getSelectedServiceData("serviceDescription")
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/map-pin.svg"
leftText: qsTr("For the region")
rightText: ApiServicesModel.getSelectedServiceData("region")
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/tag.svg"
leftText: qsTr("Price")
rightText: ApiServicesModel.getSelectedServiceData("price")
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/history.svg"
leftText: qsTr("Work period")
rightText: ApiServicesModel.getSelectedServiceData("workPeriod")
visible: rightText !== ""
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/gauge.svg"
leftText: qsTr("Speed")
rightText: ApiServicesModel.getSelectedServiceData("speed")
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/info.svg"
leftText: qsTr("Features")
rightText: ""
}
ParagraphTextType {
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
onLinkActivated: function(link) {
Qt.openUrlExternally(link)
}
textFormat: Text.RichText
text: {
var text = ApiServicesModel.getSelectedServiceData("features")
return text.replace("%1", LanguageModel.getCurrentSiteUrl())
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
}
}
BasicButtonType {
id: continueButton
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.topMargin: 32
anchors.rightMargin: 16
anchors.leftMargin: 16
anchors.bottomMargin: 32
text: qsTr("Connect")
clickedFunc: function() {
var endpoint = ApiServicesModel.getStoreEndpoint()
if (endpoint !== undefined && endpoint !== "") {
Qt.openUrlExternally(endpoint)
PageController.closePage()
PageController.closePage()
} else {
PageController.showBusyIndicator(true)
InstallController.installServiceFromApi()
PageController.showBusyIndicator(false)
}
}
}
}

View file

@ -0,0 +1,100 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
PageType {
id: root
defaultActiveFocusItem: focusItem
FlickableType {
id: fl
anchors.top: parent.top
anchors.bottom: parent.bottom
contentHeight: content.height
ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 0
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
Layout.topMargin: 20
// KeyNavigation.tab: fileButton.rightButton
}
HeaderType {
Layout.fillWidth: true
Layout.topMargin: 8
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 32
headerText: qsTr("VPN by Amnezia")
descriptionText: qsTr("Choose a VPN service that suits your needs.")
}
ListView {
id: containers
width: parent.width
height: containers.contentItem.height
spacing: 16
currentIndex: 1
interactive: false
model: ApiServicesModel
delegate: Item {
implicitWidth: containers.width
implicitHeight: delegateContent.implicitHeight
ColumnLayout {
id: delegateContent
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
CardWithIconsType {
id: card
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
headerText: name
bodyText: cardDescription
footerText: price
rightImageSource: "qrc:/images/controls/chevron-right.svg"
onClicked: {
ApiServicesModel.setServiceIndex(index)
PageController.goToPage(PageEnum.PageSetupWizardApiServiceInfo)
}
}
}
}
}
}
}
}

View file

@ -4,6 +4,7 @@ import QtQuick.Layouts
import QtQuick.Dialogs
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
@ -17,7 +18,9 @@ PageType {
target: ImportController
function onQrDecodingFinished() {
PageController.closePage()
if (Qt.platform.os === "ios") {
PageController.closePage()
}
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
}
}
@ -41,46 +44,163 @@ PageType {
Item {
id: focusItem
KeyNavigation.tab: backButton
KeyNavigation.tab: textKey.textField
}
BackButtonType {
id: backButton
Layout.topMargin: 20
KeyNavigation.tab: fileButton.rightButton
}
HeaderType {
Layout.fillWidth: true
Layout.topMargin: 8
Layout.topMargin: 24
Layout.rightMargin: 16
Layout.leftMargin: 16
headerText: qsTr("Server connection")
descriptionText: qsTr("Do not use connection codes from untrusted sources, as they may be created to intercept your data.")
headerText: qsTr("Connection")
}
Header2TextType {
ParagraphTextType {
Layout.fillWidth: true
Layout.topMargin: 32
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 24
text: qsTr("Insert the key, add a configuration file or scan the QR-code")
}
TextFieldWithHeaderType {
id: textKey
Layout.fillWidth: true
Layout.topMargin: 48
Layout.rightMargin: 16
Layout.leftMargin: 16
text: qsTr("What do you have?")
headerText: qsTr("Insert key")
buttonText: qsTr("Insert")
clickedFunc: function() {
textField.text = ""
textField.paste()
}
KeyNavigation.tab: continueButton
}
LabelWithButtonType {
id: fileButton
BasicButtonType {
id: continueButton
Layout.fillWidth: true
Layout.topMargin: 16
Layout.rightMargin: 16
Layout.leftMargin: 16
visible: textKey.textFieldText !== ""
text: qsTr("Continue")
Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunc: function() {
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
}
}
}
ParagraphTextType {
Layout.fillWidth: true
Layout.topMargin: 32
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 24
color: AmneziaStyle.color.charcoalGray
text: qsTr("Other connection options")
}
CardWithIconsType {
id: apiInstalling
visible: false
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 16
headerText: qsTr("VPN by Amnezia")
bodyText: qsTr("Connect to classic paid and free VPN services from Amnezia")
text: !ServersModel.getServersCount() ? qsTr("File with connection settings or backup") : qsTr("File with connection settings")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/folder-open.svg"
leftImageSource: "qrc:/images/controls/amnezia.svg"
KeyNavigation.tab: qrButton.visible ? qrButton.rightButton : textButton.rightButton
onClicked: function() {
PageController.showBusyIndicator(true)
var result = InstallController.fillAvailableServices()
PageController.showBusyIndicator(false)
if (result) {
PageController.goToPage(PageEnum.PageSetupWizardApiServicesList)
}
}
}
clickedFunction: function() {
CardWithIconsType {
id: manualInstalling
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 16
headerText: qsTr("Self-hosted VPN")
bodyText: qsTr("Configure Amnezia VPN on your own server")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/server.svg"
onClicked: {
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
}
}
CardWithIconsType {
id: backupRestore
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 16
visible: PageController.isStartPageVisible()
headerText: qsTr("Restore from backup")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/archive-restore.svg"
onClicked: {
var filePath = SystemController.getFileName(qsTr("Open backup file"),
qsTr("Backup files (*.backup)"))
if (filePath !== "") {
PageController.showBusyIndicator(true)
SettingsController.restoreAppConfig(filePath)
PageController.showBusyIndicator(false)
}
}
}
CardWithIconsType {
id: openFile
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 16
headerText: qsTr("File with connection settings")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/folder-search-2.svg"
onClicked: {
var nameFilter = !ServersModel.getServersCount() ? "Config or backup files (*.vpn *.ovpn *.conf *.json *.backup)" :
"Config files (*.vpn *.ovpn *.conf *.json)"
var fileName = SystemController.getFileName(qsTr("Open config file"), nameFilter)
@ -92,20 +212,22 @@ PageType {
}
}
DividerType {}
CardWithIconsType {
id: scanQr
LabelWithButtonType {
id: qrButton
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 16
visible: SettingsController.isCameraPresent()
text: qsTr("QR code")
headerText: qsTr("QR code")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/qr-code.svg"
leftImageSource: "qrc:/images/controls/scan-line.svg"
KeyNavigation.tab: textButton.rightButton
clickedFunction: function() {
onClicked: {
ImportController.startDecodingQr()
if (Qt.platform.os === "ios") {
PageController.goToPage(PageEnum.PageSetupWizardQrReader)
@ -113,26 +235,25 @@ PageType {
}
}
DividerType {
visible: SettingsController.isCameraPresent()
}
CardWithIconsType {
id: siteLink
LabelWithButtonType {
id: textButton
Layout.fillWidth: true
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 16
visible: PageController.isStartPageVisible()
headerText: qsTr("I have nothing")
text: qsTr("Key as text")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/text-cursor.svg"
leftImageSource: "qrc:/images/controls/help-circle.svg"
Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSetupWizardTextKey)
onClicked: {
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
}
}
DividerType {}
}
}
}

View file

@ -3,6 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
@ -142,6 +143,23 @@ PageType {
text: qsTr("All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties")
}
CardWithIconsType {
id: siteLink
Layout.fillWidth: true
Layout.bottomMargin: 16
headerText: qsTr("How to run your VPN server")
bodyText: qsTr("Where to get connection data, step-by-step instructions for buying a VPS")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/help-circle.svg"
onClicked: {
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl() + "/starter-guide")
}
}
}
}

View file

@ -187,10 +187,10 @@ PageType {
anchors.bottomMargin: 24
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.white
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.paleGray
borderWidth: 1
Keys.onTabPressed: lastItemTabClicked(focusItem)

View file

@ -5,6 +5,7 @@ import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
@ -46,14 +47,7 @@ PageType {
ServersModel.processedIndex = ServersModel.defaultIndex
}
PageController.goToStartPage()
if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSetupWizardStart)) {
PageController.replaceStartPage()
}
if (stackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageHome)) {
PageController.goToPageHome()
}
PageController.goToPageHome()
PageController.showNotificationMessage(finishedMessage)
}

View file

@ -95,10 +95,10 @@ PageType {
implicitHeight: 32
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.orange
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.goldenApricot
text: qsTr("More detailed")
KeyNavigation.tab: transportProtoSelector

View file

@ -6,6 +6,7 @@ import SortFilterProxyModel 0.2
import PageEnum 1.0
import ProtocolEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -14,183 +14,44 @@ import "../Components"
PageType {
id: root
property bool isControlsDisabled: false
defaultActiveFocusItem: focusItem
Connections {
target: PageController
ColumnLayout {
id: content
function onGoToPageViewConfig() {
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
anchors.fill: parent
spacing: 0
Image {
id: image
source: "qrc:/images/amneziaBigLogo.png"
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.topMargin: 32
Layout.preferredWidth: 360
Layout.preferredHeight: 287
}
function onClosePage() {
if (stackView.depth <= 1) {
PageController.hideWindow()
return
}
stackView.pop()
Item {
id: focusItem
KeyNavigation.tab: startButton
}
function onGoToPage(page, slide) {
var pagePath = PageController.getPagePath(page)
if (slide) {
stackView.push(pagePath, { "objectName" : pagePath }, StackView.PushTransition)
} else {
stackView.push(pagePath, { "objectName" : pagePath }, StackView.Immediate)
}
}
BasicButtonType {
id: startButton
Layout.fillWidth: true
Layout.bottomMargin: 48
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.alignment: Qt.AlignBottom
function onGoToStartPage() {
while (stackView.depth > 1) {
stackView.pop()
}
}
text: qsTr("Let's get started")
function onDisableControls(disabled) {
isControlsDisabled = disabled
}
function onDisableTabBar(disabled) {
isControlsDisabled = disabled
}
function onEscapePressed() {
if (isControlsDisabled) {
return
clickedFunc: function() {
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
}
PageController.closePage()
}
}
Connections {
target: SettingsController
function onRestoreBackupFinished() {
PageController.showNotificationMessage(qsTr("Settings restored from backup file"))
PageController.replaceStartPage()
}
}
Connections {
target: InstallController
function onInstallationErrorOccurred(error) {
PageController.showBusyIndicator(false)
PageController.showErrorMessage(error)
var currentPageName = stackView.currentItem.objectName
if (currentPageName === PageController.getPagePath(PageEnum.PageSetupWizardInstalling)) {
PageController.closePage()
}
}
}
Connections {
target: ImportController
function onRestoreAppConfig(data) {
PageController.showBusyIndicator(true)
SettingsController.restoreAppConfigFromData(data)
PageController.showBusyIndicator(false)
}
function onImportErrorOccurred(error, goToPageHome) {
PageController.showErrorMessage(error)
}
}
FlickableType {
id: fl
anchors.top: parent.top
anchors.bottom: parent.bottom
contentHeight: content.height
ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 0
Image {
id: image
source: "qrc:/images/amneziaBigLogo.png"
Layout.alignment: Qt.AlignCenter
Layout.topMargin: 32
Layout.leftMargin: 8
Layout.rightMargin: 8
Layout.preferredWidth: 344
Layout.preferredHeight: 279
}
ParagraphTextType {
Layout.fillWidth: true
Layout.topMargin: 50
Layout.leftMargin: 16
Layout.rightMargin: 16
text: qsTr("Free service for creating a personal VPN on your server.") +
qsTr(" Helps you access blocked content without revealing your privacy, even to VPN providers.")
}
Item {
id: focusItem
KeyNavigation.tab: startButton
}
BasicButtonType {
id: startButton
Layout.fillWidth: true
Layout.topMargin: 32
Layout.leftMargin: 16
Layout.rightMargin: 16
text: qsTr("I have the data to connect")
clickedFunc: function() {
connectionTypeSelection.open()
}
KeyNavigation.tab: startButton2
}
BasicButtonType {
id: startButton2
Layout.fillWidth: true
Layout.topMargin: 8
Layout.leftMargin: 16
Layout.rightMargin: 16
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.white
borderWidth: 1
text: qsTr("I have nothing")
clickedFunc: function() {
Qt.openUrlExternally(qsTr("https://amnezia.org/instructions/0_starter-guide"))
}
Keys.onTabPressed: lastItemTabClicked(focusItem)
}
}
}
ConnectionTypeSelectionDrawer {
id: connectionTypeSelection
onClosed: {
PageController.forceTabBarActiveFocus()
root.defaultActiveFocusItem.forceActiveFocus()
Keys.onTabPressed: lastItemTabClicked(focusItem)
}
}
}

View file

@ -3,6 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"

View file

@ -51,13 +51,7 @@ PageType {
ServersModel.processedIndex = ServersModel.defaultIndex
}
PageController.goToStartPage()
if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSetupWizardStart)) {
PageController.replaceStartPage()
}
if (stackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageHome)) {
PageController.goToPageHome()
}
PageController.goToPageHome()
}
}
@ -107,10 +101,10 @@ PageType {
implicitHeight: 32
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.orange
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.goldenApricot
text: showContent ? qsTr("Collapse content") : qsTr("Show content")
KeyNavigation.tab: connectButton
@ -139,8 +133,8 @@ PageType {
iconPath: "qrc:/images/controls/alert-circle.svg"
textColor: AmneziaStyle.color.red
imageColor: AmneziaStyle.color.red
textColor: AmneziaStyle.color.vibrantRed
imageColor: AmneziaStyle.color.vibrantRed
}
WarningType {
@ -159,7 +153,7 @@ PageType {
implicitHeight: configContent.implicitHeight
radius: 10
color: AmneziaStyle.color.blackLight
color: AmneziaStyle.color.onyxBlack
visible: showContent
@ -180,7 +174,7 @@ PageType {
Rectangle {
anchors.fill: columnContent
anchors.bottomMargin: -24
color: AmneziaStyle.color.black
color: AmneziaStyle.color.midnightBlack
opacity: 0.8
}

View file

@ -273,7 +273,7 @@ PageType {
implicitWidth: accessTypeSelectorContent.implicitWidth
implicitHeight: accessTypeSelectorContent.implicitHeight
color: AmneziaStyle.color.blackLight
color: AmneziaStyle.color.onyxBlack
radius: 16
RowLayout {
@ -327,7 +327,7 @@ PageType {
visible: accessTypeSelector.currentIndex === 0
text: qsTr("Share VPN access without the ability to manage the server")
color: AmneziaStyle.color.grey
color: AmneziaStyle.color.mutedGray
}
TextFieldWithHeaderType {
@ -658,7 +658,7 @@ PageType {
ImageButtonType {
id: closeSearchButton
image: "qrc:/images/controls/close.svg"
imageColor: AmneziaStyle.color.white
imageColor: AmneziaStyle.color.paleGray
Keys.onTabPressed: {
if (!GC.isMobile()) {
@ -806,7 +806,7 @@ PageType {
ColumnLayout
{
id: textColumn
property string textColor: AmneziaStyle.color.grey
property string textColor: AmneziaStyle.color.mutedGray
Layout.bottomMargin: 24
ParagraphTextType {
@ -853,10 +853,10 @@ PageType {
Layout.topMargin: 24
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.white
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.paleGray
borderWidth: 1
text: qsTr("Rename")
@ -946,10 +946,10 @@ PageType {
Layout.fillWidth: true
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.blackHovered
pressedColor: AmneziaStyle.color.blackPressed
disabledColor: AmneziaStyle.color.grey
textColor: AmneziaStyle.color.white
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.paleGray
borderWidth: 1
text: qsTr("Revoke")

View file

@ -67,7 +67,7 @@ PageType {
text: qsTr("We recommend that you use full access to the server only for your own additional devices.\n") +
qsTr("If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. ")
color: AmneziaStyle.color.grey
color: AmneziaStyle.color.mutedGray
}
DropDownType {

View file

@ -24,8 +24,14 @@ PageType {
target: PageController
function onGoToPageHome() {
tabBar.setCurrentIndex(0)
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
if (PageController.isStartPageVisible()) {
tabBar.visible = false
tabBarStackView.goToTabBarPage(PageEnum.PageSetupWizardStart)
} else {
tabBar.visible = true
tabBar.setCurrentIndex(0)
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
}
}
function onGoToPageSettings() {
@ -65,7 +71,6 @@ PageType {
}
function onGoToStartPage() {
connectionTypeSelection.close()
while (tabBarStackView.depth > 1) {
tabBarStackView.pop()
}
@ -78,9 +83,9 @@ PageType {
var pageName = tabBarStackView.currentItem.objectName
if ((pageName === PageController.getPagePath(PageEnum.PageShare)) ||
(pageName === PageController.getPagePath(PageEnum.PageSettings))) {
(pageName === PageController.getPagePath(PageEnum.PageSettings)) ||
(pageName === PageController.getPagePath(PageEnum.PageSetupWizardConfigSource))) {
PageController.goToPageHome()
tabBar.previousIndex = 0
} else {
PageController.closePage()
}
@ -126,6 +131,33 @@ PageType {
function onCachedProfileCleared(message) {
PageController.showNotificationMessage(message)
}
function onApiConfigRemoved(message) {
PageController.showNotificationMessage(message)
}
function onInstallServerFromApiFinished(message) {
PageController.showBusyIndicator(false)
if (!ConnectionController.isConnected) {
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
ServersModel.processedIndex = ServersModel.defaultIndex
}
PageController.goToPageHome()
PageController.showNotificationMessage(message)
}
function onChangeApiCountryFinished(message) {
PageController.showBusyIndicator(false)
PageController.goToPageHome()
PageController.showNotificationMessage(message)
}
function onReloadServerFromApiFinished(message) {
PageController.goToPageHome()
PageController.showNotificationMessage(message)
}
}
Connections {
@ -151,6 +183,12 @@ PageType {
function onImportErrorOccurred(error, goToPageHome) {
PageController.showErrorMessage(error)
}
function onRestoreAppConfig(data) {
PageController.showBusyIndicator(true)
SettingsController.restoreAppConfigFromData(data)
PageController.showBusyIndicator(false)
}
}
Connections {
@ -159,6 +197,11 @@ PageType {
function onLoggingDisableByWatcher() {
PageController.showNotificationMessage(qsTr("Logging was disabled after 14 days, log files were deleted"))
}
function onRestoreBackupFinished() {
PageController.showNotificationMessage(qsTr("Settings restored from backup file"))
PageController.goToPageHome()
}
}
StackViewType {
@ -169,31 +212,37 @@ PageType {
anchors.left: parent.left
anchors.bottom: tabBar.top
width: parent.width
height: root.height - tabBar.implicitHeight
enabled: !root.isControlsDisabled
function goToTabBarPage(page) {
connectionTypeSelection.close()
var pagePath = PageController.getPagePath(page)
tabBarStackView.clear(StackView.Immediate)
tabBarStackView.replace(pagePath, { "objectName" : pagePath }, StackView.Immediate)
}
Component.onCompleted: {
var pagePath = PageController.getPagePath(PageEnum.PageHome)
ServersModel.processedIndex = ServersModel.defaultIndex
var pagePath
if (PageController.isStartPageVisible()) {
tabBar.visible = false
pagePath = PageController.getPagePath(PageEnum.PageSetupWizardStart)
} else {
tabBar.visible = true
pagePath = PageController.getPagePath(PageEnum.PageHome)
ServersModel.processedIndex = ServersModel.defaultIndex
}
tabBarStackView.push(pagePath, { "objectName" : pagePath })
}
Keys.onPressed: function(event) {
PageController.keyPressEvent(event.key)
event.accepted = true
}
}
TabBar {
id: tabBar
property int previousIndex: 0
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
@ -203,6 +252,8 @@ PageType {
leftPadding: 96
rightPadding: 96
height: visible ? homeTabButton.implicitHeight + tabBar.topPadding + tabBar.bottomPadding : 0
enabled: !root.isControlsDisabled && !root.isTabBarDisabled
background: Shape {
@ -219,8 +270,8 @@ PageType {
PathLine { x: 0; y: 0 }
strokeWidth: 1
strokeColor: AmneziaStyle.color.greyDark
fillColor: AmneziaStyle.color.blackLight
strokeColor: AmneziaStyle.color.slateGray
fillColor: AmneziaStyle.color.onyxBlack
}
}
@ -232,7 +283,6 @@ PageType {
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
ServersModel.processedIndex = ServersModel.defaultIndex
tabBar.currentIndex = 0
tabBar.previousIndex = 0
}
KeyNavigation.tab: shareTabButton
@ -261,7 +311,6 @@ PageType {
clickedFunc: function () {
tabBarStackView.goToTabBarPage(PageEnum.PageShare)
tabBar.currentIndex = 1
tabBar.previousIndex = 1
}
KeyNavigation.tab: settingsTabButton
@ -274,7 +323,6 @@ PageType {
clickedFunc: function () {
tabBarStackView.goToTabBarPage(PageEnum.PageSettings)
tabBar.currentIndex = 2
tabBar.previousIndex = 2
}
KeyNavigation.tab: plusTabButton
@ -285,19 +333,11 @@ PageType {
isSelected: tabBar.currentIndex === 3
image: "qrc:/images/controls/plus.svg"
clickedFunc: function () {
connectionTypeSelection.open()
tabBarStackView.goToTabBarPage(PageEnum.PageSetupWizardConfigSource)
tabBar.currentIndex = 3
}
Keys.onTabPressed: PageController.forceStackActiveFocus()
}
}
ConnectionTypeSelectionDrawer {
id: connectionTypeSelection
onAboutToHide: {
PageController.forceTabBarActiveFocus()
tabBar.setCurrentIndex(tabBar.previousIndex)
}
}
}