added qr-code decoder for android
- added color change for status and navigation bar for android
This commit is contained in:
parent
b9a13d3a32
commit
0411792ca5
13 changed files with 255 additions and 58 deletions
|
|
@ -202,31 +202,6 @@ QList<QString> ExportController::getQrCodes()
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportController::saveFile()
|
void ExportController::saveFile()
|
||||||
{
|
|
||||||
QString fileExtension = ".vpn";
|
|
||||||
QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
|
||||||
QUrl fileName;
|
|
||||||
fileName = QFileDialog::getSaveFileUrl(nullptr, tr("Save AmneziaVPN config"),
|
|
||||||
QUrl::fromLocalFile(docDir + "/" + "amnezia_config"), "*" + fileExtension);
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
return;
|
|
||||||
if (!fileName.toString().endsWith(fileExtension)) {
|
|
||||||
fileName = QUrl(fileName.toString() + fileExtension);
|
|
||||||
}
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QFile save(fileName.toLocalFile());
|
|
||||||
|
|
||||||
save.open(QIODevice::WriteOnly);
|
|
||||||
save.write(m_config.toUtf8());
|
|
||||||
save.close();
|
|
||||||
|
|
||||||
QFileInfo fi(fileName.toLocalFile());
|
|
||||||
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExportController::shareFile()
|
|
||||||
{
|
{
|
||||||
#if defined Q_OS_IOS
|
#if defined Q_OS_IOS
|
||||||
ext.replace("*", "");
|
ext.replace("*", "");
|
||||||
|
|
@ -253,6 +228,28 @@ void ExportController::shareFile()
|
||||||
AndroidController::instance()->shareConfig(m_config, "amnezia_config");
|
AndroidController::instance()->shareConfig(m_config, "amnezia_config");
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString fileExtension = ".vpn";
|
||||||
|
QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||||
|
QUrl fileName;
|
||||||
|
fileName = QFileDialog::getSaveFileUrl(nullptr, tr("Save AmneziaVPN config"),
|
||||||
|
QUrl::fromLocalFile(docDir + "/" + "amnezia_config"), "*" + fileExtension);
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
if (!fileName.toString().endsWith(fileExtension)) {
|
||||||
|
fileName = QUrl(fileName.toString() + fileExtension);
|
||||||
|
}
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QFile save(fileName.toLocalFile());
|
||||||
|
|
||||||
|
save.open(QIODevice::WriteOnly);
|
||||||
|
save.write(m_config.toUtf8());
|
||||||
|
save.close();
|
||||||
|
|
||||||
|
QFileInfo fi(fileName.toLocalFile());
|
||||||
|
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QString> ExportController::generateQrCodeImageSeries(const QByteArray &data)
|
QList<QString> ExportController::generateQrCodeImageSeries(const QByteArray &data)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ public slots:
|
||||||
QList<QString> getQrCodes();
|
QList<QString> getQrCodes();
|
||||||
|
|
||||||
void saveFile();
|
void saveFile();
|
||||||
void shareFile();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void generateConfig(int type);
|
void generateConfig(int type);
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,11 @@ namespace
|
||||||
}
|
}
|
||||||
return ConfigTypes::Amnezia;
|
return ConfigTypes::Amnezia;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
ImportController *mInstance = nullptr;
|
||||||
|
constexpr auto AndroidCameraActivity = "org.amnezia.vpn.qt.CameraActivity";
|
||||||
|
#endif
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ImportController::ImportController(const QSharedPointer<ServersModel> &serversModel,
|
ImportController::ImportController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
|
|
@ -49,6 +54,7 @@ ImportController::ImportController(const QSharedPointer<ServersModel> &serversMo
|
||||||
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
|
mInstance = this;
|
||||||
// Set security screen for Android app
|
// Set security screen for Android app
|
||||||
AndroidUtils::runOnAndroidThreadSync([]() {
|
AndroidUtils::runOnAndroidThreadSync([]() {
|
||||||
QJniObject activity = AndroidUtils::getActivity();
|
QJniObject activity = AndroidUtils::getActivity();
|
||||||
|
|
@ -58,6 +64,18 @@ ImportController::ImportController(const QSharedPointer<ServersModel> &serversMo
|
||||||
window.callMethod<void>("addFlags", "(I)V", FLAG_SECURE);
|
window.callMethod<void>("addFlags", "(I)V", FLAG_SECURE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AndroidUtils::runOnAndroidThreadAsync([]() {
|
||||||
|
JNINativeMethod methods[] {
|
||||||
|
{ "passDataToDecoder", "(Ljava/lang/String;)V", reinterpret_cast<void *>(onNewQrCodeDataChunk) },
|
||||||
|
};
|
||||||
|
|
||||||
|
QJniObject javaClass(AndroidCameraActivity);
|
||||||
|
QJniEnvironment env;
|
||||||
|
jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
|
||||||
|
env->RegisterNatives(objectClass, methods, sizeof(methods) / sizeof(methods[0]));
|
||||||
|
env->DeleteLocalRef(objectClass);
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,11 +111,21 @@ void ImportController::extractConfigFromCode(QString code)
|
||||||
m_configFileName = "";
|
m_configFileName = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportController::extractConfigFromQr()
|
bool ImportController::extractConfigFromQr(const QByteArray &data)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_ANDROID
|
QJsonObject dataObj = QJsonDocument::fromJson(data).object();
|
||||||
AndroidController::instance()->startQrReaderActivity();
|
if (!dataObj.isEmpty()) {
|
||||||
#endif
|
m_config = dataObj;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ba_uncompressed = qUncompress(data);
|
||||||
|
if (!ba_uncompressed.isEmpty()) {
|
||||||
|
m_config = QJsonDocument::fromJson(ba_uncompressed).object();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ImportController::getConfig()
|
QString ImportController::getConfig()
|
||||||
|
|
@ -149,21 +177,6 @@ QJsonObject ImportController::extractAmneziaConfig(QString &data)
|
||||||
return QJsonDocument::fromJson(ba).object();
|
return QJsonDocument::fromJson(ba).object();
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool ImportController::importConnectionFromQr(const QByteArray &data)
|
|
||||||
//{
|
|
||||||
// QJsonObject dataObj = QJsonDocument::fromJson(data).object();
|
|
||||||
// if (!dataObj.isEmpty()) {
|
|
||||||
// return importConnection(dataObj);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// QByteArray ba_uncompressed = qUncompress(data);
|
|
||||||
// if (!ba_uncompressed.isEmpty()) {
|
|
||||||
// return importConnection(QJsonDocument::fromJson(ba_uncompressed).object());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
||||||
{
|
{
|
||||||
QJsonObject openVpnConfig;
|
QJsonObject openVpnConfig;
|
||||||
|
|
@ -251,3 +264,90 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
void ImportController::startDecodingQr()
|
||||||
|
{
|
||||||
|
AndroidController::instance()->startQrReaderActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImportController::stopDecodingQr()
|
||||||
|
{
|
||||||
|
QJniObject::callStaticMethod<void>(AndroidCameraActivity, "stopQrCodeReader", "()V");
|
||||||
|
emit qrDecodingFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImportController::onNewQrCodeDataChunk(JNIEnv *env, jobject thiz, jstring data)
|
||||||
|
{
|
||||||
|
Q_UNUSED(thiz);
|
||||||
|
const char *buffer = env->GetStringUTFChars(data, nullptr);
|
||||||
|
if (!buffer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString parcelBody(buffer);
|
||||||
|
env->ReleaseStringUTFChars(data, buffer);
|
||||||
|
|
||||||
|
if (mInstance != nullptr) {
|
||||||
|
if (!mInstance->m_isQrCodeProcessed) {
|
||||||
|
mInstance->m_qrCodeChunks.clear();
|
||||||
|
mInstance->m_isQrCodeProcessed = true;
|
||||||
|
mInstance->m_totalQrCodeChunksCount = 0;
|
||||||
|
mInstance->m_receivedQrCodeChunksCount = 0;
|
||||||
|
}
|
||||||
|
mInstance->parseQrCodeChunk(parcelBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImportController::parseQrCodeChunk(const QString &code)
|
||||||
|
{
|
||||||
|
// qDebug() << code;
|
||||||
|
if (!m_isQrCodeProcessed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check if chunk received
|
||||||
|
QByteArray ba = QByteArray::fromBase64(code.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
QDataStream s(&ba, QIODevice::ReadOnly);
|
||||||
|
qint16 magic;
|
||||||
|
s >> magic;
|
||||||
|
|
||||||
|
if (magic == amnezia::qrMagicCode) {
|
||||||
|
quint8 chunksCount;
|
||||||
|
s >> chunksCount;
|
||||||
|
if (m_totalQrCodeChunksCount != chunksCount) {
|
||||||
|
m_qrCodeChunks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_totalQrCodeChunksCount = chunksCount;
|
||||||
|
|
||||||
|
quint8 chunkId;
|
||||||
|
s >> chunkId;
|
||||||
|
s >> m_qrCodeChunks[chunkId];
|
||||||
|
m_receivedQrCodeChunksCount = m_qrCodeChunks.size();
|
||||||
|
|
||||||
|
if (m_qrCodeChunks.size() == m_totalQrCodeChunksCount) {
|
||||||
|
QByteArray data;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_totalQrCodeChunksCount; ++i) {
|
||||||
|
data.append(m_qrCodeChunks.value(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = extractConfigFromQr(data);
|
||||||
|
if (ok) {
|
||||||
|
m_isQrCodeProcessed = false;
|
||||||
|
stopDecodingQr();
|
||||||
|
} else {
|
||||||
|
m_qrCodeChunks.clear();
|
||||||
|
m_totalQrCodeChunksCount = 0;
|
||||||
|
m_receivedQrCodeChunksCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bool ok = extractConfigFromQr(ba);
|
||||||
|
if (ok) {
|
||||||
|
m_isQrCodeProcessed = false;
|
||||||
|
stopDecodingQr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
#include "ui/models/servers_model.h"
|
#include "ui/models/servers_model.h"
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
#include "jni.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class ImportController : public QObject
|
class ImportController : public QObject
|
||||||
{
|
{
|
||||||
|
|
@ -21,25 +24,44 @@ public slots:
|
||||||
void extractConfigFromFile();
|
void extractConfigFromFile();
|
||||||
void extractConfigFromData(QString &data);
|
void extractConfigFromData(QString &data);
|
||||||
void extractConfigFromCode(QString code);
|
void extractConfigFromCode(QString code);
|
||||||
void extractConfigFromQr();
|
bool extractConfigFromQr(const QByteArray &data);
|
||||||
QString getConfig();
|
QString getConfig();
|
||||||
QString getConfigFileName();
|
QString getConfigFileName();
|
||||||
|
|
||||||
|
#if defined Q_OS_ANDROID
|
||||||
|
void startDecodingQr();
|
||||||
|
#endif
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void importFinished();
|
void importFinished();
|
||||||
void importErrorOccurred(QString errorMessage);
|
void importErrorOccurred(QString errorMessage);
|
||||||
|
|
||||||
|
void qrDecodingFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonObject extractAmneziaConfig(QString &data);
|
QJsonObject extractAmneziaConfig(QString &data);
|
||||||
QJsonObject extractOpenVpnConfig(const QString &data);
|
QJsonObject extractOpenVpnConfig(const QString &data);
|
||||||
QJsonObject extractWireGuardConfig(const QString &data);
|
QJsonObject extractWireGuardConfig(const QString &data);
|
||||||
|
|
||||||
|
#if defined Q_OS_ANDROID
|
||||||
|
void stopDecodingQr();
|
||||||
|
static void onNewQrCodeDataChunk(JNIEnv *env, jobject thiz, jstring data);
|
||||||
|
void parseQrCodeChunk(const QString &code);
|
||||||
|
#endif
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
||||||
QJsonObject m_config;
|
QJsonObject m_config;
|
||||||
QString m_configFileName;
|
QString m_configFileName;
|
||||||
|
|
||||||
|
#if defined Q_OS_ANDROID
|
||||||
|
QMap<int, QByteArray> m_qrCodeChunks;
|
||||||
|
bool m_isQrCodeProcessed;
|
||||||
|
int m_totalQrCodeChunksCount;
|
||||||
|
int m_receivedQrCodeChunksCount;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMPORTCONTROLLER_H
|
#endif // IMPORTCONTROLLER_H
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,28 @@
|
||||||
#include "pageController.h"
|
#include "pageController.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
#include "../../platforms/android/androidutils.h"
|
||||||
|
#include <QJniObject>
|
||||||
|
#endif
|
||||||
|
|
||||||
PageController::PageController(const QSharedPointer<ServersModel> &serversModel, QObject *parent)
|
PageController::PageController(const QSharedPointer<ServersModel> &serversModel, QObject *parent)
|
||||||
: QObject(parent), m_serversModel(serversModel)
|
: QObject(parent), m_serversModel(serversModel)
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
// Change color of navigation and status bar's
|
||||||
|
auto initialPageNavigationBarColor = getInitialPageNavigationBarColor();
|
||||||
|
AndroidUtils::runOnAndroidThreadSync([&initialPageNavigationBarColor]() {
|
||||||
|
QJniObject activity = AndroidUtils::getActivity();
|
||||||
|
QJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
|
||||||
|
if (window.isValid()) {
|
||||||
|
window.callMethod<void>("addFlags", "(I)V", 0x80000000);
|
||||||
|
window.callMethod<void>("clearFlags", "(I)V", 0x04000000);
|
||||||
|
window.callMethod<void>("setStatusBarColor", "(I)V", 0xFF0E0E11);
|
||||||
|
window.callMethod<void>("setNavigationBarColor", "(I)V", initialPageNavigationBarColor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PageController::getInitialPage()
|
QString PageController::getInitialPage()
|
||||||
|
|
@ -47,3 +65,26 @@ void PageController::keyPressEvent(Qt::Key key)
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int PageController::getInitialPageNavigationBarColor()
|
||||||
|
{
|
||||||
|
if (m_serversModel->getServersCount()) {
|
||||||
|
return 0xFF1C1D21;
|
||||||
|
} else {
|
||||||
|
return 0xFF0E0E11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageController::updateNavigationBarColor(const int color)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
// Change color of navigation bar
|
||||||
|
AndroidUtils::runOnAndroidThreadSync([&color]() {
|
||||||
|
QJniObject activity = AndroidUtils::getActivity();
|
||||||
|
QJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
|
||||||
|
if (window.isValid()) {
|
||||||
|
window.callMethod<void>("setNavigationBarColor", "(I)V", color);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,9 @@ public slots:
|
||||||
void closeWindow();
|
void closeWindow();
|
||||||
void keyPressEvent(Qt::Key key);
|
void keyPressEvent(Qt::Key key);
|
||||||
|
|
||||||
|
unsigned int getInitialPageNavigationBarColor();
|
||||||
|
void updateNavigationBarColor(const int color);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void goToPageHome();
|
void goToPageHome();
|
||||||
void goToPageSettings();
|
void goToPageSettings();
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,10 @@ DrawerType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
text: Qt.platform.os === "android" ? qsTr("Share") : qsTr("Save connection code")
|
text: qsTr("Share")
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Qt.platform.os === "android" ? ExportController.shareFile() : ExportController.saveFile()
|
ExportController.saveFile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ Drawer {
|
||||||
velocity: 4
|
velocity: 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit: Transition {
|
exit: Transition {
|
||||||
SmoothedAnimation {
|
SmoothedAnimation {
|
||||||
velocity: 4
|
velocity: 4
|
||||||
|
|
@ -31,4 +32,17 @@ Drawer {
|
||||||
Overlay.modal: Rectangle {
|
Overlay.modal: Rectangle {
|
||||||
color: Qt.rgba(14/255, 14/255, 17/255, 0.8)
|
color: Qt.rgba(14/255, 14/255, 17/255, 0.8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAboutToShow: {
|
||||||
|
if (PageController.getInitialPageNavigationBarColor() !== 0xFF1C1D21) {
|
||||||
|
PageController.updateNavigationBarColor(0xFF1C1D21)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
var initialPageNavigationBarColor = PageController.getInitialPageNavigationBarColor()
|
||||||
|
if (initialPageNavigationBarColor !== 0xFF1C1D21) {
|
||||||
|
PageController.updateNavigationBarColor(initialPageNavigationBarColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,14 @@ import "../Config"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ImportController
|
||||||
|
|
||||||
|
function onQrDecodingFinished() {
|
||||||
|
goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -77,7 +85,7 @@ It's okay if a friend passed the code.")
|
||||||
leftImageSource: "qrc:/images/controls/qr-code.svg"
|
leftImageSource: "qrc:/images/controls/qr-code.svg"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
ImportController.extractConfigFromQr()
|
ImportController.startDecodingQr()
|
||||||
// goToPage(PageEnum.PageSetupWizardQrReader)
|
// goToPage(PageEnum.PageSetupWizardQrReader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,7 @@ PageType {
|
||||||
} else if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSettings)) {
|
} else if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSettings)) {
|
||||||
goToPage(PageEnum.PageSettingsServersList, false)
|
goToPage(PageEnum.PageSettingsServersList, false)
|
||||||
} else {
|
} else {
|
||||||
var pagePath = PageController.getPagePath(PageEnum.PageStart)
|
PageController.replaceStartPage()
|
||||||
stackView.replace(pagePath, { "objectName" : pagePath })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInstalledContainerFound) {
|
if (isInstalledContainerFound) {
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,7 @@ PageType {
|
||||||
} else if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSettings)) {
|
} else if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSettings)) {
|
||||||
goToPage(PageEnum.PageSettingsServersList, false)
|
goToPage(PageEnum.PageSettingsServersList, false)
|
||||||
} else {
|
} else {
|
||||||
var pagePath = PageController.getPagePath(PageEnum.PageStart)
|
PageController.replaceStartPage()
|
||||||
stackView.replace(pagePath, { "objectName" : pagePath })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Shapes
|
||||||
|
|
||||||
import PageEnum 1.0
|
import PageEnum 1.0
|
||||||
|
|
||||||
|
|
@ -81,14 +82,27 @@ PageType {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
topPadding: 8
|
topPadding: 8
|
||||||
bottomPadding: 8//34
|
bottomPadding: 8
|
||||||
leftPadding: shareTabButton.visible ? 96 : 128
|
leftPadding: shareTabButton.visible ? 96 : 128
|
||||||
rightPadding: shareTabButton.visible ? 96 : 128
|
rightPadding: shareTabButton.visible ? 96 : 128
|
||||||
|
|
||||||
background: Rectangle {
|
background: Shape {
|
||||||
border.width: 1
|
width: parent.width
|
||||||
border.color: "#2C2D30"
|
height: parent.height
|
||||||
color: "#1C1D21"
|
|
||||||
|
ShapePath {
|
||||||
|
startX: 0
|
||||||
|
startY: 0
|
||||||
|
|
||||||
|
PathLine { x: width; y: 0 }
|
||||||
|
PathLine { x: width; y: height - 1 }
|
||||||
|
PathLine { x: 0; y: height - 1 }
|
||||||
|
PathLine { x: 0; y: 0 }
|
||||||
|
|
||||||
|
strokeWidth: 1
|
||||||
|
strokeColor: "#2C2D30"
|
||||||
|
fillColor: "#1C1D21"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TabImageButtonType {
|
TabImageButtonType {
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ Window {
|
||||||
while (rootStackView.depth > 1) {
|
while (rootStackView.depth > 1) {
|
||||||
rootStackView.pop()
|
rootStackView.pop()
|
||||||
}
|
}
|
||||||
|
PageController.updateNavigationBarColor(PageController.getInitialPageNavigationBarColor())
|
||||||
rootStackView.replace(pagePath, { "objectName" : pagePath })
|
rootStackView.replace(pagePath, { "objectName" : pagePath })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue