feature: added pages for subscription settings feature
This commit is contained in:
parent
3f55f6a629
commit
b183a3b232
27 changed files with 856 additions and 287 deletions
57
client/ui/controllers/api/apiSettingsController.cpp
Normal file
57
client/ui/controllers/api/apiSettingsController.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#include "apiSettingsController.h"
|
||||
|
||||
#include "core/controllers/gatewayController.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
constexpr char serviceInfo[] = "service_info";
|
||||
|
||||
constexpr char apiConfig[] = "api_config";
|
||||
constexpr char authData[] = "auth_data";
|
||||
}
|
||||
|
||||
const int requestTimeoutMsecs = 12 * 1000; // 12 secs
|
||||
}
|
||||
|
||||
ApiSettingsController::ApiSettingsController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ApiAccountInfoModel> &apiAccountInfoModel, const std::shared_ptr<Settings> &settings,
|
||||
QObject *parent)
|
||||
: QObject(parent), m_serversModel(serversModel), m_apiAccountInfoModel(apiAccountInfoModel), m_settings(settings)
|
||||
{
|
||||
}
|
||||
|
||||
ApiSettingsController::~ApiSettingsController()
|
||||
{
|
||||
}
|
||||
|
||||
bool ApiSettingsController::getAccountInfo()
|
||||
{
|
||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), requestTimeoutMsecs);
|
||||
|
||||
auto processedIndex = m_serversModel->getProcessedServerIndex();
|
||||
auto serverConfig = m_serversModel->getServerConfig(processedIndex);
|
||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||
auto authData = serverConfig.value(configKey::authData).toObject();
|
||||
|
||||
QJsonObject apiPayload;
|
||||
apiPayload[configKey::userCountryCode] = apiConfig.value(configKey::userCountryCode).toString();
|
||||
apiPayload[configKey::serviceType] = apiConfig.value(configKey::serviceType).toString();
|
||||
apiPayload[configKey::authData] = authData;
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/account_info"), apiPayload, responseBody);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
// emit errorOccured(errorCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject accountInfo = QJsonDocument::fromJson(responseBody).object();
|
||||
m_apiAccountInfoModel->updateModel(accountInfo, serverConfig);
|
||||
|
||||
return true;
|
||||
}
|
||||
27
client/ui/controllers/api/apiSettingsController.h
Normal file
27
client/ui/controllers/api/apiSettingsController.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef APISETTINGSCONTROLLER_H
|
||||
#define APISETTINGSCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "ui/models/api/apiAccountInfoModel.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
class ApiSettingsController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ApiSettingsController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ApiAccountInfoModel> &apiAccountInfoModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||
~ApiSettingsController();
|
||||
|
||||
public slots:
|
||||
bool getAccountInfo();
|
||||
|
||||
private:
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ApiAccountInfoModel> m_apiAccountInfoModel;
|
||||
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
};
|
||||
|
||||
#endif // APISETTINGSCONTROLLER_H
|
||||
2
client/ui/controllers/api/importController.cpp
Normal file
2
client/ui/controllers/api/importController.cpp
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#include "importController.h"
|
||||
|
||||
24
client/ui/controllers/api/importController.h
Normal file
24
client/ui/controllers/api/importController.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef IMPORTCONTROLLER_H
|
||||
#define IMPORTCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "ui/models/api/apiAccountInfoModel.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
// namespace api
|
||||
// {
|
||||
// class ImportController : public QObject
|
||||
// {
|
||||
// Q_OBJECT
|
||||
// public:
|
||||
// ImportController(const QSharedPointer<ServersModel> &serversModel, QSharedPointer<AccountInfoModel> &accountInfoModel);
|
||||
// ~ImportController();
|
||||
|
||||
// private:
|
||||
// QSharedPointer<ServersModel> m_serversModel;
|
||||
// QSharedPointer<AccountInfoModel> m_accountInfoModel;
|
||||
// };
|
||||
// }
|
||||
|
||||
#endif // IMPORTCONTROLLER_H
|
||||
|
|
@ -832,6 +832,7 @@ bool InstallController::updateServiceFromApi(const int serverIndex, const QStrin
|
|||
auto authData = serverConfig.value(configKey::authData).toObject();
|
||||
|
||||
QJsonObject newServerConfig;
|
||||
|
||||
ErrorCode errorCode = apiController.getConfigForService(
|
||||
m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
|
||||
apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ namespace PageLoader
|
|||
PageSettingsAppSplitTunneling,
|
||||
PageSettingsApiServerInfo,
|
||||
PageSettingsApiAvailableCountries,
|
||||
PageSettingsApiSupport,
|
||||
PageSettingsApiInstructions,
|
||||
|
||||
PageServiceSftpSettings,
|
||||
PageServiceTorWebsiteSettings,
|
||||
|
|
@ -55,7 +57,7 @@ namespace PageLoader
|
|||
PageProtocolOpenVpnSettings,
|
||||
PageProtocolShadowSocksSettings,
|
||||
PageProtocolCloakSettings,
|
||||
PageProtocolXraySettings,
|
||||
PageProtocolXraySettings,
|
||||
PageProtocolWireGuardSettings,
|
||||
PageProtocolAwgSettings,
|
||||
PageProtocolIKev2Settings,
|
||||
|
|
@ -106,7 +108,7 @@ public slots:
|
|||
int incrementDrawerDepth();
|
||||
int decrementDrawerDepth();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onShowErrorMessage(amnezia::ErrorCode errorCode);
|
||||
|
||||
signals:
|
||||
|
|
|
|||
105
client/ui/models/api/apiAccountInfoModel.cpp
Normal file
105
client/ui/models/api/apiAccountInfoModel.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#include "apiAccountInfoModel.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/api/apiUtils.h"
|
||||
#include "logger.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
Logger logger("AccountInfoModel");
|
||||
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char availableCountries[] = "available_countries";
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serverCountryName[] = "server_country_name";
|
||||
constexpr char lastUpdated[] = "last_updated";
|
||||
constexpr char activeDeviceCount[] = "active_device_count";
|
||||
constexpr char maxDeviceCount[] = "max_device_count";
|
||||
constexpr char subscriptionEndDate[] = "subscription_end_date";
|
||||
}
|
||||
}
|
||||
|
||||
ApiAccountInfoModel::ApiAccountInfoModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int ApiAccountInfoModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(rowCount()))
|
||||
return QVariant();
|
||||
|
||||
switch (role) {
|
||||
case SubscriptionStatusRole: {
|
||||
return ApiUtils::isSubscriptionExpired(m_accountInfoData.subscriptionEndDate) ? tr("Inactive") : tr("Active");
|
||||
}
|
||||
case EndDateRole: {
|
||||
return QDateTime::fromString(m_accountInfoData.subscriptionEndDate, Qt::ISODate).toLocalTime().toString("d MMM yyyy");
|
||||
}
|
||||
case ConnectedDevicesRole: {
|
||||
return tr("%1 out of %2").arg(m_accountInfoData.activeDeviceCount).arg(m_accountInfoData.maxDeviceCount);
|
||||
}
|
||||
// case ServiceDescriptionRole: {
|
||||
// return apiServiceData.serviceInfo.name;
|
||||
// }
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ApiAccountInfoModel::updateModel(const QJsonObject &accountInfoObject, const QJsonObject &serverConfig)
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
AccountInfoData accountInfoData;
|
||||
|
||||
auto availableCountries = accountInfoObject.value(configKey::availableCountries).toArray();
|
||||
for (const auto &country : availableCountries) {
|
||||
auto countryObject = country.toObject();
|
||||
CountryInfo countryInfo;
|
||||
countryInfo.serverCountryCode = countryObject.value(configKey::serverCountryCode).toString();
|
||||
countryInfo.serverCountryName = countryObject.value(configKey::serverCountryName).toString();
|
||||
countryInfo.lastUpdated = countryObject.value(configKey::lastUpdated).toString();
|
||||
|
||||
accountInfoData.AvailableCountries.push_back(countryInfo);
|
||||
}
|
||||
|
||||
accountInfoData.activeDeviceCount = accountInfoObject.value(configKey::activeDeviceCount).toInt();
|
||||
accountInfoData.maxDeviceCount = accountInfoObject.value(configKey::maxDeviceCount).toInt();
|
||||
accountInfoData.subscriptionEndDate = accountInfoObject.value(configKey::subscriptionEndDate).toString();
|
||||
|
||||
m_accountInfoData = accountInfoData;
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QVariant ApiAccountInfoModel::data(const QString &roleString)
|
||||
{
|
||||
QModelIndex modelIndex = index(0);
|
||||
auto roles = roleNames();
|
||||
for (auto it = roles.begin(); it != roles.end(); it++) {
|
||||
if (QString(it.value()) == roleString) {
|
||||
return data(modelIndex, it.key());
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ApiAccountInfoModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[SubscriptionStatusRole] = "subscriptionStatus";
|
||||
roles[EndDateRole] = "endDate";
|
||||
roles[ConnectedDevicesRole] = "connectedDevices";
|
||||
roles[ServiceDescriptionRole] = "serviceDescription";
|
||||
|
||||
return roles;
|
||||
}
|
||||
55
client/ui/models/api/apiAccountInfoModel.h
Normal file
55
client/ui/models/api/apiAccountInfoModel.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef APIACCOUNTINFOMODEL_H
|
||||
#define APIACCOUNTINFOMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
class ApiAccountInfoModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
SubscriptionStatusRole = Qt::UserRole + 1,
|
||||
ConnectedDevicesRole,
|
||||
ServiceDescriptionRole,
|
||||
EndDateRole
|
||||
};
|
||||
|
||||
explicit ApiAccountInfoModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonObject &accountInfoObject, const QJsonObject &serverConfig);
|
||||
QVariant data(const QString &roleString);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
struct CountryInfo
|
||||
{
|
||||
QString serverCountryCode;
|
||||
QString serverCountryName;
|
||||
QString lastUpdated;
|
||||
};
|
||||
|
||||
struct AccountInfoData
|
||||
{
|
||||
QString subscriptionEndDate;
|
||||
int activeDeviceCount;
|
||||
int maxDeviceCount;
|
||||
|
||||
QString vpnKey;
|
||||
|
||||
QVector<CountryInfo> AvailableCountries;
|
||||
};
|
||||
|
||||
AccountInfoData m_accountInfoData;
|
||||
};
|
||||
|
||||
#endif // APIACCOUNTINFOMODEL_H
|
||||
|
|
@ -112,9 +112,10 @@ ListView {
|
|||
ServersModel.processedIndex = index
|
||||
|
||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||
ApiSettingsController.getAccountInfo()
|
||||
|
||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||
|
||||
} else {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
||||
}
|
||||
|
|
|
|||
38
client/ui/qml/Controls2/ListViewType.qml
Normal file
38
client/ui/qml/Controls2/ListViewType.qml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
ListView {
|
||||
id: root
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBarType {}
|
||||
|
||||
clip: true
|
||||
reuseItems: true
|
||||
snapMode: ListView.SnapToItem
|
||||
}
|
||||
|
|
@ -299,9 +299,10 @@ PageType {
|
|||
ServersModel.processedIndex = ServersModel.defaultIndex
|
||||
|
||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||
ApiSettingsController.getAccountInfo()
|
||||
|
||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||
|
||||
} else {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ PageType {
|
|||
readonly property string description: qsTr("For reviews and bug reports")
|
||||
readonly property string imageSource: "qrc:/images/controls/mail.svg"
|
||||
readonly property var handler: function() {
|
||||
GC.copyToClipBoard(title)
|
||||
PageController.showNotificationMessage(qsTr("Copied"))
|
||||
Qt.openUrlExternally(qsTr("mailto:support@amnezia.org"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
87
client/ui/qml/Pages2/PageSettingsApiInstructions.qml
Normal file
87
client/ui/qml/Pages2/PageSettingsApiInstructions.qml
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
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
|
||||
|
||||
QtObject {
|
||||
id: windows
|
||||
|
||||
readonly property string title: qsTr("Windows")
|
||||
readonly property string imageSource: "qrc:/images/controls/external-link.svg"
|
||||
readonly property var handler: function() {
|
||||
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: linux
|
||||
|
||||
readonly property string title: qsTr("Windows")
|
||||
readonly property string imageSource: "qrc:/images/controls/external-link.svg"
|
||||
readonly property var handler: function() {
|
||||
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
|
||||
}
|
||||
}
|
||||
|
||||
property list<QtObject> instructionsModel: [
|
||||
windows,
|
||||
linux
|
||||
]
|
||||
|
||||
ListViewType {
|
||||
id: listView
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
model: instructionsModel
|
||||
|
||||
header: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
}
|
||||
|
||||
HeaderType {
|
||||
id: header
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
|
||||
headerText: "Support"
|
||||
descriptionText: qsTr("Our technical support specialists are ready to help you at any time")
|
||||
}
|
||||
}
|
||||
|
||||
delegate: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
LabelWithButtonType {
|
||||
id: telegramButton
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 6
|
||||
|
||||
text: title
|
||||
leftImageSource: imageSource
|
||||
|
||||
clickedFunction: handler
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,28 +18,19 @@ PageType {
|
|||
id: root
|
||||
|
||||
property list<QtObject> labelsModel: [
|
||||
regionObject,
|
||||
priceObject,
|
||||
statusObject,
|
||||
endDateObject,
|
||||
speedObject
|
||||
deviceCountObject
|
||||
]
|
||||
|
||||
QtObject {
|
||||
id: regionObject
|
||||
id: statusObject
|
||||
|
||||
readonly property string title: qsTr("For the region")
|
||||
readonly property string contentKey: "region"
|
||||
readonly property string title: qsTr("Subscription status")
|
||||
readonly property string contentKey: "subscriptionStatus"
|
||||
readonly property string objectImageSource: "qrc:/images/controls/map-pin.svg"
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: priceObject
|
||||
|
||||
readonly property string title: qsTr("Price")
|
||||
readonly property string contentKey: "price"
|
||||
readonly property string objectImageSource: "qrc:/images/controls/tag.svg"
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: endDateObject
|
||||
|
||||
|
|
@ -49,10 +40,10 @@ PageType {
|
|||
}
|
||||
|
||||
QtObject {
|
||||
id: speedObject
|
||||
id: deviceCountObject
|
||||
|
||||
readonly property string title: qsTr("Speed")
|
||||
readonly property string contentKey: "speed"
|
||||
readonly property string title: qsTr("Connected devices")
|
||||
readonly property string contentKey: "connectedDevices"
|
||||
readonly property string objectImageSource: "qrc:/images/controls/gauge.svg"
|
||||
}
|
||||
|
||||
|
|
@ -83,43 +74,11 @@ PageType {
|
|||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
ListViewType {
|
||||
id: listView
|
||||
|
||||
property bool isFocusable: true
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Keys.onTabPressed: {
|
||||
FocusController.nextKeyTabItem()
|
||||
}
|
||||
|
||||
Keys.onBacktabPressed: {
|
||||
FocusController.previousKeyTabItem()
|
||||
}
|
||||
|
||||
Keys.onUpPressed: {
|
||||
FocusController.nextKeyUpItem()
|
||||
}
|
||||
|
||||
Keys.onDownPressed: {
|
||||
FocusController.nextKeyDownItem()
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
FocusController.nextKeyLeftItem()
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
FocusController.nextKeyRightItem()
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBarType {}
|
||||
|
||||
clip: true
|
||||
reuseItems: true
|
||||
snapMode: ListView.SnapToItem
|
||||
|
||||
model: labelsModel
|
||||
|
||||
header: ColumnLayout {
|
||||
|
|
@ -175,7 +134,7 @@ PageType {
|
|||
|
||||
imageSource: objectImageSource
|
||||
leftText: title
|
||||
rightText: ApiServicesModel.getSelectedServiceData(contentKey)
|
||||
rightText: ApiAccountInfoModel.data(contentKey)
|
||||
|
||||
visible: rightText !== ""
|
||||
}
|
||||
|
|
@ -185,53 +144,61 @@ PageType {
|
|||
width: listView.width
|
||||
spacing: 0
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
visible: text !== ""
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: supportUuid
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
text: qsTr("Support tag")
|
||||
descriptionText: SettingsController.getInstallationUuid()
|
||||
visible: false
|
||||
|
||||
descriptionOnTop: true
|
||||
|
||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||
rightImageColor: AmneziaStyle.color.paleGray
|
||||
text: qsTr("Subscription key")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
GC.copyToClipBoard(descriptionText)
|
||||
PageController.showNotificationMessage(qsTr("Copied"))
|
||||
if (!GC.isMobile()) {
|
||||
this.rightButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Configuration files")
|
||||
|
||||
descriptionText: qsTr("To connect the router")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Support")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiSupport)
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("How to connect on another devicey")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiInstructions)
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
BasicButtonType {
|
||||
id: resetButton
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
|
|
|||
107
client/ui/qml/Pages2/PageSettingsApiSupport.qml
Normal file
107
client/ui/qml/Pages2/PageSettingsApiSupport.qml
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
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
|
||||
|
||||
ColumnLayout {
|
||||
id: backButtonLayout
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
}
|
||||
|
||||
|
||||
HeaderType {
|
||||
id: header
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
|
||||
headerText: "Support"
|
||||
descriptionText: qsTr("Our technical support specialists are ready to help you at any time")
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Telegram")
|
||||
descriptionText: qsTr("@amnezia_premium_support_bot")
|
||||
rightImageSource: "qrc:/images/controls/external-link.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
Qt.openUrlExternally(qsTr("https://t.me/amnezia_premium_support_bot"))
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Mail")
|
||||
descriptionText: qsTr("support@amnezia.org")
|
||||
rightImageSource: "qrc:/images/controls/external-link.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
Qt.openUrlExternally(qsTr("mailto:support@amnezia.org"))
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Site")
|
||||
descriptionText: qsTr("amnezia.org")
|
||||
rightImageSource: "qrc:/images/controls/external-link.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: supportUuid
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Support tag")
|
||||
descriptionText: SettingsController.getInstallationUuid()
|
||||
|
||||
descriptionOnTop: true
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,16 +36,6 @@ PageType {
|
|||
PageController.showErrorMessage(message)
|
||||
}
|
||||
|
||||
function onRemoveProcessedServerFinished(finishedMessage) {
|
||||
if (!ServersModel.getServersCount()) {
|
||||
PageController.goToPageHome()
|
||||
} else {
|
||||
PageController.goToStartPage()
|
||||
PageController.goToPage(PageEnum.PageSettingsServersList)
|
||||
}
|
||||
PageController.showNotificationMessage(finishedMessage)
|
||||
}
|
||||
|
||||
function onRebootProcessedServerFinished(finishedMessage) {
|
||||
PageController.showNotificationMessage(finishedMessage)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,12 +95,9 @@ PageType {
|
|||
ServersModel.processedIndex = index
|
||||
|
||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||
ApiSettingsController.getAccountInfo()
|
||||
|
||||
} else {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
||||
}
|
||||
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
||||
} else {
|
||||
PageController.goToPage(PageEnum.PageSettingsServerInfo)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,16 @@ PageType {
|
|||
PageController.goToPageHome()
|
||||
PageController.showNotificationMessage(message)
|
||||
}
|
||||
|
||||
function onRemoveProcessedServerFinished(finishedMessage) {
|
||||
if (!ServersModel.getServersCount()) {
|
||||
PageController.goToPageHome()
|
||||
} else {
|
||||
PageController.goToStartPage()
|
||||
PageController.goToPage(PageEnum.PageSettingsServersList)
|
||||
}
|
||||
PageController.showNotificationMessage(finishedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue