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,8 +57,7 @@ if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
qt_standard_project_setup()
|
qt_standard_project_setup()
|
||||||
qt_add_executable(${PROJECT} MANUAL_FINALIZATION
|
qt_add_executable(${PROJECT} MANUAL_FINALIZATION)
|
||||||
core/controllers/gatewayController.h core/controllers/gatewayController.cpp)
|
|
||||||
|
|
||||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
||||||
|
@ -111,8 +110,8 @@ if(IS_CI)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/3rdparty.cmake)
|
include(${CMAKE_CURRENT_LIST_DIR}/cmake/3rdparty.cmake)
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/cmake/sources.cmake)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../ipc
|
${CMAKE_CURRENT_LIST_DIR}/../ipc
|
||||||
|
@ -121,167 +120,22 @@ include_directories(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/../version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
|
||||||
|
|
||||||
set(HEADERS ${HEADERS}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/migrations.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/amnezia_application.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/containers/containers_defs.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/defs.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/server_defs.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/apiController.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/vpnConfigurationController.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/qml_register_protocols.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/pages.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.h
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/sshclient.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/networkUtilities.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/serialization.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/transfer.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/enums/apiEnums.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../common/logger/logger.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/utils/qmlUtils.h
|
|
||||||
)
|
|
||||||
|
|
||||||
# Mozilla headres
|
|
||||||
set(HEADERS ${HEADERS}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/models/server.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/shared/ipaddress.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/shared/leakdetector.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/controllerimpl.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/localsocketcontroller.h
|
|
||||||
)
|
|
||||||
|
|
||||||
include_directories(mozilla)
|
include_directories(mozilla)
|
||||||
include_directories(mozilla/shared)
|
include_directories(mozilla/shared)
|
||||||
include_directories(mozilla/models)
|
include_directories(mozilla/models)
|
||||||
|
|
||||||
if(NOT IOS)
|
configure_file(${CMAKE_CURRENT_LIST_DIR}/../version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||||
set(HEADERS ${HEADERS}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.h
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT ANDROID)
|
|
||||||
set(HEADERS ${HEADERS}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(SOURCES ${SOURCES}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/migrations.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/amnezia_application.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/containers/containers_defs.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/server_defs.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/apiController.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/vpnConfigurationController.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/sshclient.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/networkUtilities.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/outbound.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/inbound.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/ss.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/ssd.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vless.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/trojan.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vmess.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vmess_new.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../common/logger/logger.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/utils/qmlUtils.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# Mozilla sources
|
|
||||||
set(SOURCES ${SOURCES}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/models/server.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/shared/ipaddress.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/shared/leakdetector.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mozilla/localsocketcontroller.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
target_compile_definitions(${PROJECT} PRIVATE "MZ_DEBUG")
|
target_compile_definitions(${PROJECT} PRIVATE "MZ_DEBUG")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT IOS)
|
|
||||||
set(SOURCES ${SOURCES}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.cpp
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT ANDROID)
|
|
||||||
set(SOURCES ${SOURCES}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.cpp
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(GLOB COMMON_FILES_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/*.h)
|
|
||||||
file(GLOB COMMON_FILES_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/*.cpp)
|
|
||||||
|
|
||||||
file(GLOB_RECURSE PAGE_LOGIC_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/pages_logic/*.h)
|
|
||||||
file(GLOB_RECURSE PAGE_LOGIC_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/pages_logic/*.cpp)
|
|
||||||
|
|
||||||
file(GLOB CONFIGURATORS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/configurators/*.h)
|
|
||||||
file(GLOB CONFIGURATORS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/configurators/*.cpp)
|
|
||||||
|
|
||||||
file(GLOB UI_MODELS_H CONFIGURE_DEPENDS
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/*.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/services/*.h
|
|
||||||
)
|
|
||||||
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/*.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/models/services/*.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.h)
|
|
||||||
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.cpp)
|
|
||||||
|
|
||||||
set(HEADERS ${HEADERS}
|
|
||||||
${COMMON_FILES_H}
|
|
||||||
${PAGE_LOGIC_H}
|
|
||||||
${CONFIGURATORS_H}
|
|
||||||
${UI_MODELS_H}
|
|
||||||
${UI_CONTROLLERS_H}
|
|
||||||
)
|
|
||||||
set(SOURCES ${SOURCES}
|
|
||||||
${COMMON_FILES_CPP}
|
|
||||||
${PAGE_LOGIC_CPP}
|
|
||||||
${CONFIGURATORS_CPP}
|
|
||||||
${UI_MODELS_CPP}
|
|
||||||
${UI_CONTROLLERS_CPP}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
configure_file(
|
configure_file(
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/windows/amneziavpn.rc.in
|
${CMAKE_CURRENT_LIST_DIR}/platforms/windows/amneziavpn.rc.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/amneziavpn.rc
|
${CMAKE_CURRENT_BINARY_DIR}/amneziavpn.rc
|
||||||
)
|
)
|
||||||
|
|
||||||
set(HEADERS ${HEADERS}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(SOURCES ${SOURCES}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(RESOURCES ${RESOURCES}
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/amneziavpn.rc
|
|
||||||
)
|
|
||||||
|
|
||||||
set(LIBS ${LIBS}
|
set(LIBS ${LIBS}
|
||||||
user32
|
user32
|
||||||
rasapi32
|
rasapi32
|
||||||
|
@ -325,30 +179,6 @@ endif()
|
||||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
message("Client desktop build")
|
message("Client desktop build")
|
||||||
add_compile_definitions(AMNEZIA_DESKTOP)
|
add_compile_definitions(AMNEZIA_DESKTOP)
|
||||||
|
|
||||||
set(HEADERS ${HEADERS}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/ipcclient.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/privileged_process.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/systemtray_notificationhandler.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnprotocol.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/xrayprotocol.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/awgprotocol.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(SOURCES ${SOURCES}
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/ipcclient.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/privileged_process.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/systemtray_notificationhandler.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnprotocol.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/xrayprotocol.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/awgprotocol.cpp
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
|
|
|
@ -378,6 +378,9 @@ void AmneziaApplication::initModels()
|
||||||
});
|
});
|
||||||
connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
|
connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
|
||||||
[this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
|
[this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
|
||||||
|
|
||||||
|
m_apiAccountInfoModel.reset(new ApiAccountInfoModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("ApiAccountInfoModel", m_apiAccountInfoModel.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmneziaApplication::initControllers()
|
void AmneziaApplication::initControllers()
|
||||||
|
@ -463,4 +466,7 @@ void AmneziaApplication::initControllers()
|
||||||
|
|
||||||
m_systemController.reset(new SystemController(m_settings));
|
m_systemController.reset(new SystemController(m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get());
|
m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get());
|
||||||
|
|
||||||
|
m_apiSettingsController.reset(new ApiSettingsController(m_serversModel, m_apiAccountInfoModel, m_settings));
|
||||||
|
m_engine->rootContext()->setContextProperty("ApiSettingsController", m_apiSettingsController.get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "ui/controllers/sitesController.h"
|
#include "ui/controllers/sitesController.h"
|
||||||
#include "ui/controllers/systemController.h"
|
#include "ui/controllers/systemController.h"
|
||||||
#include "ui/controllers/appSplitTunnelingController.h"
|
#include "ui/controllers/appSplitTunnelingController.h"
|
||||||
|
// #include "ui/controllers/api/importController.h"
|
||||||
|
#include "ui/controllers/api/apiSettingsController.h"
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
#include "ui/models/languageModel.h"
|
#include "ui/models/languageModel.h"
|
||||||
#include "ui/models/protocols/cloakConfigModel.h"
|
#include "ui/models/protocols/cloakConfigModel.h"
|
||||||
|
@ -48,6 +50,7 @@
|
||||||
#include "ui/models/appSplitTunnelingModel.h"
|
#include "ui/models/appSplitTunnelingModel.h"
|
||||||
#include "ui/models/apiServicesModel.h"
|
#include "ui/models/apiServicesModel.h"
|
||||||
#include "ui/models/apiCountryModel.h"
|
#include "ui/models/apiCountryModel.h"
|
||||||
|
#include "ui/models/api/apiAccountInfoModel.h"
|
||||||
|
|
||||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||||
|
|
||||||
|
@ -104,6 +107,7 @@ private:
|
||||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||||
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
||||||
QSharedPointer<ApiCountryModel> m_apiCountryModel;
|
QSharedPointer<ApiCountryModel> m_apiCountryModel;
|
||||||
|
QSharedPointer<ApiAccountInfoModel> m_apiAccountInfoModel;
|
||||||
|
|
||||||
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
||||||
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
||||||
|
@ -114,7 +118,6 @@ private:
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QScopedPointer<SftpConfigModel> m_sftpConfigModel;
|
QScopedPointer<SftpConfigModel> m_sftpConfigModel;
|
||||||
QScopedPointer<Socks5ProxyConfigModel> m_socks5ConfigModel;
|
QScopedPointer<Socks5ProxyConfigModel> m_socks5ConfigModel;
|
||||||
|
|
||||||
|
@ -135,6 +138,8 @@ private:
|
||||||
QScopedPointer<SystemController> m_systemController;
|
QScopedPointer<SystemController> m_systemController;
|
||||||
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
||||||
|
|
||||||
|
QScopedPointer<ApiSettingsController> m_apiSettingsController;
|
||||||
|
|
||||||
QNetworkAccessManager *m_nam;
|
QNetworkAccessManager *m_nam;
|
||||||
|
|
||||||
QMetaObject::Connection m_reloadConfigErrorOccurredConnection;
|
QMetaObject::Connection m_reloadConfigErrorOccurredConnection;
|
||||||
|
|
189
client/cmake/sources.cmake
Normal file
189
client/cmake/sources.cmake
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||||
|
|
||||||
|
set(HEADERS ${HEADERS}
|
||||||
|
${CLIENT_ROOT_DIR}/migrations.h
|
||||||
|
${CLIENT_ROOT_DIR}/../ipc/ipc.h
|
||||||
|
${CLIENT_ROOT_DIR}/amnezia_application.h
|
||||||
|
${CLIENT_ROOT_DIR}/containers/containers_defs.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/defs.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/errorstrings.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/scripts_registry.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/server_defs.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/apiController.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/gatewayController.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/serverController.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/vpnConfigurationController.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/protocols_defs.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/qml_register_protocols.h
|
||||||
|
${CLIENT_ROOT_DIR}/ui/pages.h
|
||||||
|
${CLIENT_ROOT_DIR}/ui/qautostart.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/vpnprotocol.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/sshclient.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/networkUtilities.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/serialization.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/transfer.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/enums/apiEnums.h
|
||||||
|
${CLIENT_ROOT_DIR}/../common/logger/logger.h
|
||||||
|
${CLIENT_ROOT_DIR}/utils/qmlUtils.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/api/apiUtils.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# Mozilla headres
|
||||||
|
set(HEADERS ${HEADERS}
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/models/server.h
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/shared/ipaddress.h
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/shared/leakdetector.h
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/controllerimpl.h
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/localsocketcontroller.h
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT IOS)
|
||||||
|
set(HEADERS ${HEADERS}
|
||||||
|
${CLIENT_ROOT_DIR}/platforms/ios/QRCodeReaderBase.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ANDROID)
|
||||||
|
set(HEADERS ${HEADERS}
|
||||||
|
${CLIENT_ROOT_DIR}/ui/notificationhandler.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(SOURCES ${SOURCES}
|
||||||
|
${CLIENT_ROOT_DIR}/migrations.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/amnezia_application.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/containers/containers_defs.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/errorstrings.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/scripts_registry.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/server_defs.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/apiController.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/gatewayController.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/serverController.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/controllers/vpnConfigurationController.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/protocols_defs.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/ui/qautostart.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/vpnprotocol.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/sshclient.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/networkUtilities.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/outbound.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/inbound.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/ss.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/ssd.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/vless.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/trojan.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/vmess.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/serialization/vmess_new.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/../common/logger/logger.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/utils/qmlUtils.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/api/apiUtils.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Mozilla sources
|
||||||
|
set(SOURCES ${SOURCES}
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/models/server.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/shared/ipaddress.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/shared/leakdetector.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/mozilla/localsocketcontroller.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT IOS)
|
||||||
|
set(SOURCES ${SOURCES}
|
||||||
|
${CLIENT_ROOT_DIR}/platforms/ios/QRCodeReaderBase.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ANDROID)
|
||||||
|
set(SOURCES ${SOURCES}
|
||||||
|
${CLIENT_ROOT_DIR}/ui/notificationhandler.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(GLOB COMMON_FILES_H CONFIGURE_DEPENDS ${CLIENT_ROOT_DIR}/*.h)
|
||||||
|
file(GLOB COMMON_FILES_CPP CONFIGURE_DEPENDS ${CLIENT_ROOT_DIR}/*.cpp)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE PAGE_LOGIC_H CONFIGURE_DEPENDS ${CLIENT_ROOT_DIR}/ui/pages_logic/*.h)
|
||||||
|
file(GLOB_RECURSE PAGE_LOGIC_CPP CONFIGURE_DEPENDS ${CLIENT_ROOT_DIR}/ui/pages_logic/*.cpp)
|
||||||
|
|
||||||
|
file(GLOB CONFIGURATORS_H CONFIGURE_DEPENDS ${CLIENT_ROOT_DIR}/configurators/*.h)
|
||||||
|
file(GLOB CONFIGURATORS_CPP CONFIGURE_DEPENDS ${CLIENT_ROOT_DIR}/configurators/*.cpp)
|
||||||
|
|
||||||
|
file(GLOB UI_MODELS_H CONFIGURE_DEPENDS
|
||||||
|
${CLIENT_ROOT_DIR}/ui/models/*.h
|
||||||
|
${CLIENT_ROOT_DIR}/ui/models/protocols/*.h
|
||||||
|
${CLIENT_ROOT_DIR}/ui/models/services/*.h
|
||||||
|
${CLIENT_ROOT_DIR}/ui/models/api/*.h
|
||||||
|
)
|
||||||
|
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS
|
||||||
|
${CLIENT_ROOT_DIR}/ui/models/*.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/ui/models/protocols/*.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/ui/models/services/*.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/ui/models/api/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS
|
||||||
|
${CLIENT_ROOT_DIR}/ui/controllers/*.h
|
||||||
|
${CLIENT_ROOT_DIR}/ui/controllers/api/*.h
|
||||||
|
)
|
||||||
|
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS
|
||||||
|
${CLIENT_ROOT_DIR}/ui/controllers/*.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/ui/controllers/api/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(HEADERS ${HEADERS}
|
||||||
|
${COMMON_FILES_H}
|
||||||
|
${PAGE_LOGIC_H}
|
||||||
|
${CONFIGURATORS_H}
|
||||||
|
${UI_MODELS_H}
|
||||||
|
${UI_CONTROLLERS_H}
|
||||||
|
)
|
||||||
|
set(SOURCES ${SOURCES}
|
||||||
|
${COMMON_FILES_CPP}
|
||||||
|
${PAGE_LOGIC_CPP}
|
||||||
|
${CONFIGURATORS_CPP}
|
||||||
|
${UI_MODELS_CPP}
|
||||||
|
${UI_CONTROLLERS_CPP}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(HEADERS ${HEADERS}
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/ikev2_vpn_protocol_windows.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES ${SOURCES}
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/ikev2_vpn_protocol_windows.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(RESOURCES ${RESOURCES}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/amneziavpn.rc
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
|
message("Client desktop build")
|
||||||
|
add_compile_definitions(AMNEZIA_DESKTOP)
|
||||||
|
|
||||||
|
set(HEADERS ${HEADERS}
|
||||||
|
${CLIENT_ROOT_DIR}/core/ipcclient.h
|
||||||
|
${CLIENT_ROOT_DIR}/core/privileged_process.h
|
||||||
|
${CLIENT_ROOT_DIR}/ui/systemtray_notificationhandler.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/openvpnprotocol.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/openvpnovercloakprotocol.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/shadowsocksvpnprotocol.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/wireguardprotocol.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/xrayprotocol.h
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/awgprotocol.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES ${SOURCES}
|
||||||
|
${CLIENT_ROOT_DIR}/core/ipcclient.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/core/privileged_process.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/ui/systemtray_notificationhandler.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/openvpnprotocol.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/openvpnovercloakprotocol.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/shadowsocksvpnprotocol.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/wireguardprotocol.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/xrayprotocol.cpp
|
||||||
|
${CLIENT_ROOT_DIR}/protocols/awgprotocol.cpp
|
||||||
|
)
|
||||||
|
endif()
|
10
client/core/api/apiUtils.cpp
Normal file
10
client/core/api/apiUtils.cpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "apiUtils.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
bool ApiUtils::isSubscriptionExpired(const QString &subscriptionEndDate)
|
||||||
|
{
|
||||||
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QDateTime endDate = QDateTime::fromString(subscriptionEndDate, Qt::ISODateWithMs);
|
||||||
|
return endDate < now;
|
||||||
|
}
|
11
client/core/api/apiUtils.h
Normal file
11
client/core/api/apiUtils.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef APIUTILS_H
|
||||||
|
#define APIUTILS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace ApiUtils
|
||||||
|
{
|
||||||
|
bool isSubscriptionExpired(const QString &subscriptionEndDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // APIUTILS_H
|
|
@ -8,8 +8,8 @@
|
||||||
#include "amnezia_application.h"
|
#include "amnezia_application.h"
|
||||||
#include "configurators/wireguard_configurator.h"
|
#include "configurators/wireguard_configurator.h"
|
||||||
#include "core/enums/apiEnums.h"
|
#include "core/enums/apiEnums.h"
|
||||||
#include "version.h"
|
|
||||||
#include "gatewayController.h"
|
#include "gatewayController.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -213,10 +213,29 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorCode ApiController::getAccountInfo(const QString &userCountryCode, const QString &serviceType, const QJsonObject &authData,
|
||||||
|
QByteArray &responseBody)
|
||||||
|
{
|
||||||
|
GatewayController gatewayController(m_gatewayEndpoint, m_isDevEnvironment, requestTimeoutMsecs);
|
||||||
|
|
||||||
|
QJsonObject apiPayload;
|
||||||
|
apiPayload[configKey::userCountryCode] = userCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = serviceType;
|
||||||
|
apiPayload[configKey::authData] = authData;
|
||||||
|
|
||||||
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/account_info"), apiPayload, responseBody);
|
||||||
|
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
ErrorCode ApiController::getServicesList(QByteArray &responseBody)
|
ErrorCode ApiController::getServicesList(QByteArray &responseBody)
|
||||||
{
|
{
|
||||||
GatewayController gatewayController(m_gatewayEndpoint, m_isDevEnvironment, requestTimeoutMsecs);
|
GatewayController gatewayController(m_gatewayEndpoint, m_isDevEnvironment, requestTimeoutMsecs);
|
||||||
ErrorCode errorCode = gatewayController.get("%1v1/services", responseBody);
|
|
||||||
|
QJsonObject apiPayload;
|
||||||
|
apiPayload[configKey::osVersion] = QSysInfo::productType();
|
||||||
|
|
||||||
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/services"), apiPayload, responseBody);
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
if (!responseBody.contains("services")) {
|
if (!responseBody.contains("services")) {
|
||||||
return ErrorCode::ApiServicesMissingError;
|
return ErrorCode::ApiServicesMissingError;
|
||||||
|
@ -254,3 +273,24 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
|
||||||
|
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorCode ApiController::getNativeConfig(const QString &userCountryCode, const QString &serviceType, const QString &protocol,
|
||||||
|
const QString &serverCountryCode, const QJsonObject &authData, QString &nativeConfig)
|
||||||
|
{
|
||||||
|
GatewayController gatewayController(m_gatewayEndpoint, m_isDevEnvironment, requestTimeoutMsecs);
|
||||||
|
|
||||||
|
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
||||||
|
|
||||||
|
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
||||||
|
apiPayload[configKey::userCountryCode] = userCountryCode;
|
||||||
|
apiPayload[configKey::serverCountryCode] = serverCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = serviceType;
|
||||||
|
apiPayload[configKey::authData] = authData;
|
||||||
|
|
||||||
|
QByteArray responseBody;
|
||||||
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/country_config"), apiPayload, responseBody);
|
||||||
|
|
||||||
|
nativeConfig = responseBody;
|
||||||
|
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
|
@ -19,9 +19,14 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void updateServerConfigFromApi(const QString &installationUuid, const int serverIndex, QJsonObject serverConfig);
|
void updateServerConfigFromApi(const QString &installationUuid, const int serverIndex, QJsonObject serverConfig);
|
||||||
|
|
||||||
|
ErrorCode getAccountInfo(const QString &userCountryCode, const QString &serviceType, const QJsonObject &authData,
|
||||||
|
QByteArray &responseBody);
|
||||||
ErrorCode getServicesList(QByteArray &responseBody);
|
ErrorCode getServicesList(QByteArray &responseBody);
|
||||||
ErrorCode getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
|
ErrorCode getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
|
||||||
const QString &protocol, const QString &serverCountryCode, const QJsonObject &authData, QJsonObject &serverConfig);
|
const QString &protocol, const QString &serverCountryCode, const QJsonObject &authData,
|
||||||
|
QJsonObject &serverConfig);
|
||||||
|
ErrorCode getNativeConfig(const QString &userCountryCode, const QString &serviceType, const QString &protocol,
|
||||||
|
const QString &serverCountryCode, const QJsonObject &authData, QString &nativeConfig);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void errorOccurred(ErrorCode errorCode);
|
void errorOccurred(ErrorCode errorCode);
|
||||||
|
|
|
@ -225,6 +225,9 @@
|
||||||
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
||||||
<file>ui/qml/Pages2/PageStart.qml</file>
|
<file>ui/qml/Pages2/PageStart.qml</file>
|
||||||
<file>ui/qml/Components/RenameServerDrawer.qml</file>
|
<file>ui/qml/Components/RenameServerDrawer.qml</file>
|
||||||
|
<file>ui/qml/Controls2/ListViewType.qml</file>
|
||||||
|
<file>ui/qml/Pages2/PageSettingsApiSupport.qml</file>
|
||||||
|
<file>ui/qml/Pages2/PageSettingsApiInstructions.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/countriesFlags">
|
<qresource prefix="/countriesFlags">
|
||||||
<file>images/flagKit/ZW.svg</file>
|
<file>images/flagKit/ZW.svg</file>
|
||||||
|
|
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();
|
auto authData = serverConfig.value(configKey::authData).toObject();
|
||||||
|
|
||||||
QJsonObject newServerConfig;
|
QJsonObject newServerConfig;
|
||||||
|
|
||||||
ErrorCode errorCode = apiController.getConfigForService(
|
ErrorCode errorCode = apiController.getConfigForService(
|
||||||
m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
|
m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
|
||||||
apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode,
|
apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode,
|
||||||
|
|
|
@ -33,6 +33,8 @@ namespace PageLoader
|
||||||
PageSettingsAppSplitTunneling,
|
PageSettingsAppSplitTunneling,
|
||||||
PageSettingsApiServerInfo,
|
PageSettingsApiServerInfo,
|
||||||
PageSettingsApiAvailableCountries,
|
PageSettingsApiAvailableCountries,
|
||||||
|
PageSettingsApiSupport,
|
||||||
|
PageSettingsApiInstructions,
|
||||||
|
|
||||||
PageServiceSftpSettings,
|
PageServiceSftpSettings,
|
||||||
PageServiceTorWebsiteSettings,
|
PageServiceTorWebsiteSettings,
|
||||||
|
@ -55,7 +57,7 @@ namespace PageLoader
|
||||||
PageProtocolOpenVpnSettings,
|
PageProtocolOpenVpnSettings,
|
||||||
PageProtocolShadowSocksSettings,
|
PageProtocolShadowSocksSettings,
|
||||||
PageProtocolCloakSettings,
|
PageProtocolCloakSettings,
|
||||||
PageProtocolXraySettings,
|
PageProtocolXraySettings,
|
||||||
PageProtocolWireGuardSettings,
|
PageProtocolWireGuardSettings,
|
||||||
PageProtocolAwgSettings,
|
PageProtocolAwgSettings,
|
||||||
PageProtocolIKev2Settings,
|
PageProtocolIKev2Settings,
|
||||||
|
@ -106,7 +108,7 @@ public slots:
|
||||||
int incrementDrawerDepth();
|
int incrementDrawerDepth();
|
||||||
int decrementDrawerDepth();
|
int decrementDrawerDepth();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onShowErrorMessage(amnezia::ErrorCode errorCode);
|
void onShowErrorMessage(amnezia::ErrorCode errorCode);
|
||||||
|
|
||||||
signals:
|
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
|
ServersModel.processedIndex = index
|
||||||
|
|
||||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||||
|
ApiSettingsController.getAccountInfo()
|
||||||
|
|
||||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
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
|
ServersModel.processedIndex = ServersModel.defaultIndex
|
||||||
|
|
||||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||||
|
ApiSettingsController.getAccountInfo()
|
||||||
|
|
||||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,7 @@ PageType {
|
||||||
readonly property string description: qsTr("For reviews and bug reports")
|
readonly property string description: qsTr("For reviews and bug reports")
|
||||||
readonly property string imageSource: "qrc:/images/controls/mail.svg"
|
readonly property string imageSource: "qrc:/images/controls/mail.svg"
|
||||||
readonly property var handler: function() {
|
readonly property var handler: function() {
|
||||||
GC.copyToClipBoard(title)
|
Qt.openUrlExternally(qsTr("mailto:support@amnezia.org"))
|
||||||
PageController.showNotificationMessage(qsTr("Copied"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
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
|
id: root
|
||||||
|
|
||||||
property list<QtObject> labelsModel: [
|
property list<QtObject> labelsModel: [
|
||||||
regionObject,
|
statusObject,
|
||||||
priceObject,
|
|
||||||
endDateObject,
|
endDateObject,
|
||||||
speedObject
|
deviceCountObject
|
||||||
]
|
]
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: regionObject
|
id: statusObject
|
||||||
|
|
||||||
readonly property string title: qsTr("For the region")
|
readonly property string title: qsTr("Subscription status")
|
||||||
readonly property string contentKey: "region"
|
readonly property string contentKey: "subscriptionStatus"
|
||||||
readonly property string objectImageSource: "qrc:/images/controls/map-pin.svg"
|
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 {
|
QtObject {
|
||||||
id: endDateObject
|
id: endDateObject
|
||||||
|
|
||||||
|
@ -49,10 +40,10 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: speedObject
|
id: deviceCountObject
|
||||||
|
|
||||||
readonly property string title: qsTr("Speed")
|
readonly property string title: qsTr("Connected devices")
|
||||||
readonly property string contentKey: "speed"
|
readonly property string contentKey: "connectedDevices"
|
||||||
readonly property string objectImageSource: "qrc:/images/controls/gauge.svg"
|
readonly property string objectImageSource: "qrc:/images/controls/gauge.svg"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,43 +74,11 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ListViewType {
|
||||||
id: listView
|
id: listView
|
||||||
|
|
||||||
property bool isFocusable: true
|
|
||||||
|
|
||||||
anchors.fill: parent
|
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
|
model: labelsModel
|
||||||
|
|
||||||
header: ColumnLayout {
|
header: ColumnLayout {
|
||||||
|
@ -175,7 +134,7 @@ PageType {
|
||||||
|
|
||||||
imageSource: objectImageSource
|
imageSource: objectImageSource
|
||||||
leftText: title
|
leftText: title
|
||||||
rightText: ApiServicesModel.getSelectedServiceData(contentKey)
|
rightText: ApiAccountInfoModel.data(contentKey)
|
||||||
|
|
||||||
visible: rightText !== ""
|
visible: rightText !== ""
|
||||||
}
|
}
|
||||||
|
@ -185,53 +144,61 @@ PageType {
|
||||||
width: listView.width
|
width: listView.width
|
||||||
spacing: 0
|
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 {
|
LabelWithButtonType {
|
||||||
id: supportUuid
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 32
|
||||||
|
|
||||||
text: qsTr("Support tag")
|
visible: false
|
||||||
descriptionText: SettingsController.getInstallationUuid()
|
|
||||||
|
|
||||||
descriptionOnTop: true
|
text: qsTr("Subscription key")
|
||||||
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
|
||||||
rightImageColor: AmneziaStyle.color.paleGray
|
|
||||||
|
|
||||||
clickedFunction: function() {
|
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 {
|
BasicButtonType {
|
||||||
id: resetButton
|
id: resetButton
|
||||||
Layout.alignment: Qt.AlignHCenter
|
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)
|
PageController.showErrorMessage(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRemoveProcessedServerFinished(finishedMessage) {
|
|
||||||
if (!ServersModel.getServersCount()) {
|
|
||||||
PageController.goToPageHome()
|
|
||||||
} else {
|
|
||||||
PageController.goToStartPage()
|
|
||||||
PageController.goToPage(PageEnum.PageSettingsServersList)
|
|
||||||
}
|
|
||||||
PageController.showNotificationMessage(finishedMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRebootProcessedServerFinished(finishedMessage) {
|
function onRebootProcessedServerFinished(finishedMessage) {
|
||||||
PageController.showNotificationMessage(finishedMessage)
|
PageController.showNotificationMessage(finishedMessage)
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,12 +95,9 @@ PageType {
|
||||||
ServersModel.processedIndex = index
|
ServersModel.processedIndex = index
|
||||||
|
|
||||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
ApiSettingsController.getAccountInfo()
|
||||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
|
||||||
|
|
||||||
} else {
|
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
||||||
PageController.goToPage(PageEnum.PageSettingsApiServerInfo)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
PageController.goToPage(PageEnum.PageSettingsServerInfo)
|
PageController.goToPage(PageEnum.PageSettingsServerInfo)
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,16 @@ PageType {
|
||||||
PageController.goToPageHome()
|
PageController.goToPageHome()
|
||||||
PageController.showNotificationMessage(message)
|
PageController.showNotificationMessage(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onRemoveProcessedServerFinished(finishedMessage) {
|
||||||
|
if (!ServersModel.getServersCount()) {
|
||||||
|
PageController.goToPageHome()
|
||||||
|
} else {
|
||||||
|
PageController.goToStartPage()
|
||||||
|
PageController.goToPage(PageEnum.PageSettingsServersList)
|
||||||
|
}
|
||||||
|
PageController.showNotificationMessage(finishedMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue