added pages for sftp and tor website settings
This commit is contained in:
parent
75489c00c2
commit
5d677a9115
22 changed files with 713 additions and 6 deletions
|
@ -129,8 +129,16 @@ file(GLOB_RECURSE PAGE_LOGIC_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/
|
|||
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)
|
||||
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/models/*.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.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)
|
||||
|
|
|
@ -267,6 +267,9 @@ void AmneziaApplication::initModels()
|
|||
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
|
||||
m_engine->rootContext()->setContextProperty("Ikev2ConfigModel", m_ikev2ConfigModel.get());
|
||||
#endif
|
||||
|
||||
m_sftpConfigModel.reset(new SftpConfigModel(this));
|
||||
m_engine->rootContext()->setContextProperty("SftpConfigModel", m_sftpConfigModel.get());
|
||||
}
|
||||
|
||||
void AmneziaApplication::initControllers()
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||
#include "ui/models/protocols_model.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
#include "ui/models/services/sftpConfigModel.h"
|
||||
|
||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||
|
||||
|
@ -91,6 +92,8 @@ private:
|
|||
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
||||
#endif
|
||||
|
||||
QScopedPointer<SftpConfigModel> m_sftpConfigModel;
|
||||
|
||||
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||
QScopedPointer<NotificationHandler> m_notificationHandler;
|
||||
|
||||
|
|
4
client/images/controls/copy.svg
Normal file
4
client/images/controls/copy.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 9H11C9.89543 9 9 9.89543 9 11V20C9 21.1046 9.89543 22 11 22H20C21.1046 22 22 21.1046 22 20V11C22 9.89543 21.1046 9 20 9Z" stroke="#CBCBCB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5 15H4C3.46957 15 2.96086 14.7893 2.58579 14.4142C2.21071 14.0391 2 13.5304 2 13V4C2 3.46957 2.21071 2.96086 2.58579 2.58579C2.96086 2.21071 3.46957 2 4 2H13C13.5304 2 14.0391 2.21071 14.4142 2.58579C14.7893 2.96086 15 3.46957 15 4V5" stroke="#CBCBCB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 649 B |
|
@ -65,6 +65,7 @@ namespace amnezia
|
|||
constexpr char wireguard[] = "wireguard";
|
||||
constexpr char shadowsocks[] = "shadowsocks";
|
||||
constexpr char cloak[] = "cloak";
|
||||
constexpr char sftp[] = "sftp";
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -275,5 +275,8 @@
|
|||
<file>ui/qml/Pages2/PageProtocolCloakSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolRaw.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
|
||||
<file>ui/qml/Pages2/PageServiceSftpSettings.qml</file>
|
||||
<file>images/controls/copy.svg</file>
|
||||
<file>ui/qml/Pages2/PageServiceTorWebsiteSettings.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "installController.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QJsonObject>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "core/errorstrings.h"
|
||||
#include "core/servercontroller.h"
|
||||
|
@ -214,3 +216,80 @@ void InstallController::setShouldCreateServer(bool shouldCreateServer)
|
|||
{
|
||||
m_shouldCreateServer = shouldCreateServer;
|
||||
}
|
||||
|
||||
void InstallController::mountSftpDrive(const QString &port, const QString &password, const QString &username)
|
||||
{
|
||||
QString mountPath;
|
||||
QString cmd;
|
||||
|
||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||
ServerCredentials serverCredentials =
|
||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||
QString hostname = serverCredentials.hostName;
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
mountPath = getNextDriverLetter() + ":";
|
||||
// QString cmd = QString("net use \\\\sshfs\\%1@x.x.x.x!%2 /USER:%1 %3")
|
||||
// .arg(labelTftpUserNameText())
|
||||
// .arg(labelTftpPortText())
|
||||
// .arg(labelTftpPasswordText());
|
||||
|
||||
cmd = "C:\\Program Files\\SSHFS-Win\\bin\\sshfs.exe";
|
||||
#elif defined AMNEZIA_DESKTOP
|
||||
mountPath =
|
||||
QString("%1/sftp:%2:%3").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), hostname, port);
|
||||
QDir dir(mountPath);
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(mountPath);
|
||||
}
|
||||
|
||||
cmd = "/usr/local/bin/sshfs";
|
||||
#endif
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
QSharedPointer<QProcess> process;
|
||||
process.reset(new QProcess());
|
||||
m_sftpMountProcesses.append(process);
|
||||
process->setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
connect(process.get(), &QProcess::readyRead, this, [this, process, mountPath]() {
|
||||
QString s = process->readAll();
|
||||
if (s.contains("The service sshfs has been started")) {
|
||||
QDesktopServices::openUrl(QUrl("file:///" + mountPath));
|
||||
}
|
||||
qDebug() << s;
|
||||
});
|
||||
|
||||
process->setProgram(cmd);
|
||||
|
||||
QString args = QString("%1@%2:/ %3 "
|
||||
"-o port=%4 "
|
||||
"-f "
|
||||
"-o reconnect "
|
||||
"-o rellinks "
|
||||
"-o fstypename=SSHFS "
|
||||
"-o ssh_command=/usr/bin/ssh.exe "
|
||||
"-o UserKnownHostsFile=/dev/null "
|
||||
"-o StrictHostKeyChecking=no "
|
||||
"-o password_stdin")
|
||||
.arg(username, hostname, mountPath, port);
|
||||
|
||||
// args.replace("\n", " ");
|
||||
// args.replace("\r", " ");
|
||||
// #ifndef Q_OS_WIN
|
||||
// args.replace("reconnect-orellinks", "");
|
||||
// #endif
|
||||
process->setArguments(args.split(" ", Qt::SkipEmptyParts));
|
||||
process->start();
|
||||
process->waitForStarted(50);
|
||||
if (process->state() != QProcess::Running) {
|
||||
qDebug() << "onPushButtonSftpMountDriveClicked process not started";
|
||||
qDebug() << args;
|
||||
} else {
|
||||
process->write((password + "\n").toUtf8());
|
||||
}
|
||||
|
||||
// qDebug().noquote() << "onPushButtonSftpMountDriveClicked" << args;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define INSTALLCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/defs.h"
|
||||
|
@ -28,6 +29,8 @@ public slots:
|
|||
|
||||
QRegularExpression ipAddressPortRegExp();
|
||||
|
||||
void mountSftpDrive(const QString &port, const QString &password, const QString &username);
|
||||
|
||||
signals:
|
||||
void installContainerFinished(bool isInstalledContainerFound);
|
||||
void installServerFinished(bool isInstalledContainerFound);
|
||||
|
@ -52,6 +55,8 @@ private:
|
|||
ServerCredentials m_currentlyInstalledServerCredentials;
|
||||
|
||||
bool m_shouldCreateServer;
|
||||
|
||||
QList<QSharedPointer<QProcess>> m_sftpMountProcesses;
|
||||
};
|
||||
|
||||
#endif // INSTALLCONTROLLER_H
|
||||
|
|
|
@ -29,6 +29,9 @@ namespace PageLoader
|
|||
PageSettingsAbout,
|
||||
PageSettingsLogging,
|
||||
|
||||
PageServiceSftpSettings,
|
||||
PageServiceTorWebsiteSettings,
|
||||
|
||||
PageSetupWizardStart,
|
||||
PageSetupWizardCredentials,
|
||||
PageSetupWizardProtocols,
|
||||
|
|
|
@ -118,6 +118,11 @@ QString ContainersModel::getCurrentlyProcessedContainerName()
|
|||
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_currentlyProcessedContainerIndex));
|
||||
}
|
||||
|
||||
QJsonObject ContainersModel::getCurrentlyProcessedContainerConfig()
|
||||
{
|
||||
return qvariant_cast<QJsonObject>(data(index(m_currentlyProcessedContainerIndex), ConfigRole));
|
||||
}
|
||||
|
||||
void ContainersModel::removeAllContainers()
|
||||
{
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ public slots:
|
|||
int getCurrentlyProcessedContainerIndex();
|
||||
|
||||
QString getCurrentlyProcessedContainerName();
|
||||
QJsonObject getCurrentlyProcessedContainerConfig();
|
||||
|
||||
void removeAllContainers();
|
||||
void removeCurrentlyProcessedContainer();
|
||||
|
|
|
@ -106,6 +106,11 @@ int ServersModel::getCurrentlyProcessedServerIndex()
|
|||
return m_currentlyProcessedServerIndex;
|
||||
}
|
||||
|
||||
QString ServersModel::getCurrentlyProcessedServerHostName()
|
||||
{
|
||||
return qvariant_cast<QString>(data(m_currentlyProcessedServerIndex, HostNameRole));
|
||||
}
|
||||
|
||||
bool ServersModel::isDefaultServerCurrentlyProcessed()
|
||||
{
|
||||
return m_defaultServerIndex == m_currentlyProcessedServerIndex;
|
||||
|
|
|
@ -45,6 +45,8 @@ public slots:
|
|||
void setCurrentlyProcessedServerIndex(const int index);
|
||||
int getCurrentlyProcessedServerIndex();
|
||||
|
||||
QString getCurrentlyProcessedServerHostName();
|
||||
|
||||
void addServer(const QJsonObject &server);
|
||||
void removeServer();
|
||||
|
||||
|
|
64
client/ui/models/services/sftpConfigModel.cpp
Normal file
64
client/ui/models/services/sftpConfigModel.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "sftpConfigModel.h"
|
||||
|
||||
#include "protocols/protocols_defs.h"
|
||||
|
||||
SftpConfigModel::SftpConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int SftpConfigModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant SftpConfigModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString();
|
||||
case Roles::UserNameRole:
|
||||
return m_protocolConfig.value(config_key::userName).toString(protocols::sftp::defaultUserName);
|
||||
case Roles::PasswordRole: return m_protocolConfig.value(config_key::password).toString();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void SftpConfigModel::updateModel(const QJsonObject &config)
|
||||
{
|
||||
beginResetModel();
|
||||
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||
|
||||
m_fullConfig = config;
|
||||
QJsonObject protocolConfig = config.value(config_key::sftp).toObject();
|
||||
|
||||
m_protocolConfig.insert(config_key::userName,
|
||||
protocolConfig.value(config_key::userName).toString(protocols::sftp::defaultUserName));
|
||||
|
||||
m_protocolConfig.insert(config_key::password, protocolConfig.value(config_key::password).toString());
|
||||
|
||||
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString());
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QJsonObject SftpConfigModel::getConfig()
|
||||
{
|
||||
m_fullConfig.insert(config_key::sftp, m_protocolConfig);
|
||||
return m_fullConfig;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> SftpConfigModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[PortRole] = "port";
|
||||
roles[UserNameRole] = "username";
|
||||
roles[PasswordRole] = "password";
|
||||
|
||||
return roles;
|
||||
}
|
39
client/ui/models/services/sftpConfigModel.h
Normal file
39
client/ui/models/services/sftpConfigModel.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef SFTPCONFIGMODEL_H
|
||||
#define SFTPCONFIGMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
class SftpConfigModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
PortRole = Qt::UserRole + 1,
|
||||
UserNameRole,
|
||||
PasswordRole
|
||||
};
|
||||
|
||||
explicit SftpConfigModel(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 &config);
|
||||
QJsonObject getConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
DockerContainer m_container;
|
||||
QJsonObject m_protocolConfig;
|
||||
QJsonObject m_fullConfig;
|
||||
};
|
||||
|
||||
#endif // SFTPCONFIGMODEL_H
|
|
@ -92,6 +92,7 @@ ListView {
|
|||
if (isInstalled) {
|
||||
var containerIndex = root.model.mapToSource(index)
|
||||
ContainersModel.setCurrentlyProcessedContainerIndex(containerIndex)
|
||||
|
||||
if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) {
|
||||
ProtocolsModel.updateModel(config)
|
||||
goToPage(PageEnum.PageProtocolRaw)
|
||||
|
@ -114,6 +115,16 @@ ListView {
|
|||
goToPage(PageEnum.PageProtocolIKev2Settings)
|
||||
break
|
||||
}
|
||||
case ContainerEnum.Sftp: {
|
||||
SftpConfigModel.updateModel(config)
|
||||
goToPage(PageEnum.PageServiceSftpSettings)
|
||||
break
|
||||
}
|
||||
case ContainerEnum.TorWebSite: {
|
||||
goToPage(PageEnum.PageServiceTorWebsiteSettings)
|
||||
break
|
||||
}
|
||||
|
||||
default: {
|
||||
if (serviceType !== ProtocolEnum.Other) { //todo disable settings for dns container
|
||||
ProtocolsModel.updateModel(config)
|
||||
|
|
|
@ -16,6 +16,10 @@ Item {
|
|||
property string leftImageSource
|
||||
|
||||
property string textColor: "#d7d8db"
|
||||
property string descriptionColor: "#878B91"
|
||||
property string rightImageColor: "#878B91"
|
||||
|
||||
property bool descriptionOnTop: false
|
||||
|
||||
implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
|
||||
implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
|
||||
|
@ -53,26 +57,41 @@ Item {
|
|||
}
|
||||
|
||||
ColumnLayout {
|
||||
property real textLineHeight: 21.6
|
||||
property real descriptionTextLineHeight: 16
|
||||
|
||||
property int textPixelSize: 18
|
||||
property int descriptionTextSize: 13
|
||||
|
||||
ListItemTitleType {
|
||||
text: root.text
|
||||
color: root.textColor
|
||||
color: root.descriptionOnTop ? root.descriptionColor : root.textColor
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
lineHeight: root.descriptionOnTop ? parent.descriptionTextLineHeight : parent.textLineHeight
|
||||
font.pixelSize: root.descriptionOnTop ? parent.descriptionTextSize : parent.textPixelSize
|
||||
font.letterSpacing: root.descriptionOnTop ? 0.02 : 0
|
||||
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
|
||||
CaptionTextType {
|
||||
id: description
|
||||
|
||||
color: "#878B91"
|
||||
color: root.descriptionOnTop ? root.textColor : root.descriptionColor
|
||||
text: root.descriptionText
|
||||
|
||||
visible: root.descriptionText !== ""
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
lineHeight: root.descriptionOnTop ? parent.textLineHeight : parent.descriptionTextLineHeight
|
||||
font.pixelSize: root.descriptionOnTop ? parent.textPixelSize : parent.descriptionTextSize
|
||||
font.letterSpacing: root.descriptionOnTop ? 0 : 0.02
|
||||
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
@ -83,6 +102,7 @@ Item {
|
|||
|
||||
hoverEnabled: false
|
||||
image: rightImageSource
|
||||
imageColor: rightImageColor
|
||||
visible: rightImageSource ? true : false
|
||||
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
|
|
@ -10,5 +10,5 @@ Text {
|
|||
font.family: "PT Root UI VF"
|
||||
font.letterSpacing: 0.02
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
|
|
@ -9,5 +9,5 @@ Text {
|
|||
font.weight: 400
|
||||
font.family: "PT Root UI VF"
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
|
|
@ -413,6 +413,8 @@ PageType {
|
|||
|
||||
BasicButtonType {
|
||||
Layout.topMargin: 24
|
||||
Layout.leftMargin: -8
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
|
|
280
client/ui/qml/Pages2/PageServiceSftpSettings.qml
Normal file
280
client/ui/qml/Pages2/PageServiceSftpSettings.qml
Normal file
|
@ -0,0 +1,280 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import PageEnum 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
//todo move to main?
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onInstallationErrorOccurred(errorMessage) {
|
||||
PageController.showErrorMessage(errorMessage)
|
||||
}
|
||||
|
||||
function onUpdateContainerFinished() {
|
||||
//todo change to notification
|
||||
PageController.showErrorMessage(qsTr("Settings updated successfully"))
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
|
||||
BackButtonType {
|
||||
}
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.implicitHeight
|
||||
|
||||
Column {
|
||||
id: content
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
|
||||
|
||||
ListView {
|
||||
id: listview
|
||||
|
||||
width: parent.width
|
||||
height: listview.contentItem.height
|
||||
|
||||
clip: true
|
||||
interactive: false
|
||||
|
||||
model: SftpConfigModel
|
||||
|
||||
delegate: Item {
|
||||
implicitWidth: listview.width
|
||||
implicitHeight: col.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: col
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
spacing: 0
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: qsTr("SFTP settings")
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
text: qsTr("Host")
|
||||
descriptionText: ServersModel.getCurrentlyProcessedServerHostName()
|
||||
|
||||
descriptionOnTop: true
|
||||
|
||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||
rightImageColor: "#D7D8DB"
|
||||
|
||||
clickedFunction: function() {
|
||||
col.copyToClipBoard(descriptionText)
|
||||
}
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Port")
|
||||
descriptionText: port
|
||||
|
||||
descriptionOnTop: true
|
||||
|
||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||
rightImageColor: "#D7D8DB"
|
||||
|
||||
clickedFunction: function() {
|
||||
col.copyToClipBoard(descriptionText)
|
||||
}
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Login")
|
||||
descriptionText: username
|
||||
|
||||
descriptionOnTop: true
|
||||
|
||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||
rightImageColor: "#D7D8DB"
|
||||
|
||||
clickedFunction: function() {
|
||||
col.copyToClipBoard(descriptionText)
|
||||
}
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Password")
|
||||
descriptionText: password
|
||||
|
||||
descriptionOnTop: true
|
||||
|
||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||
rightImageColor: "#D7D8DB"
|
||||
|
||||
clickedFunction: function() {
|
||||
col.copyToClipBoard(descriptionText)
|
||||
}
|
||||
}
|
||||
|
||||
TextEdit{
|
||||
id: clipboard
|
||||
visible: false
|
||||
}
|
||||
|
||||
function copyToClipBoard(text) {
|
||||
clipboard.text = text
|
||||
clipboard.selectAll()
|
||||
clipboard.copy()
|
||||
clipboard.select(0, 0)
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 24
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
disabledColor: "#878B91"
|
||||
textColor: "#D7D8DB"
|
||||
borderWidth: 1
|
||||
|
||||
text: qsTr("Mount folder on device")
|
||||
|
||||
onClicked: {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.mountSftpDrive(port, password, username)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
readonly property string windowsFirstLink: "<a href=\"https://github.com/billziss-gh/winfsp/releases/latest\" style=\"color: #FBB26A;\">WinFsp</a>"
|
||||
readonly property string windowsSecondLink: "<a href=\"https://github.com/billziss-gh/sshfs-win/releases\" style=\"color: #FBB26A;\">SSHFS-Win</a>"
|
||||
|
||||
readonly property string macosFirstLink: "<a href=\"https://osxfuse.github.io/\" style=\"color: #FBB26A;\">macFUSE</a>"
|
||||
readonly property string macosSecondLink: "<a href=\"https://osxfuse.github.io/\" style=\"color: #FBB26A;\">SSHFS</a>"
|
||||
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
textFormat: Text.RichText
|
||||
text: {
|
||||
var str = qsTr("In order to mount remote SFTP folder as local drive, perform following steps: <br>")
|
||||
if (Qt.platform.os === "windows") {
|
||||
str += qsTr("<br>1. Install the latest version of ") + windowsFirstLink + "\n"
|
||||
str += qsTr("<br>2. Install the latest version of ") + windowsSecondLink + "\n"
|
||||
} else if (Qt.platform.os === "osx") {
|
||||
str += qsTr("<br>1. Install the latest version of ") + macosFirstLink + "\n"
|
||||
str += qsTr("<br>2. Install the latest version of ") + macosSecondLink + "\n"
|
||||
} else if (Qt.platform.os === "linux") {
|
||||
return ""
|
||||
} else return ""
|
||||
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.topMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
Layout.leftMargin: 8
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
disabledColor: "#878B91"
|
||||
textColor: "#FBB26A"
|
||||
|
||||
text: qsTr("Detailed instructions")
|
||||
|
||||
onClicked: {
|
||||
// Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 16
|
||||
Layout.leftMargin: 8
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
textColor: "#EB5757"
|
||||
|
||||
text: qsTr("Remove SFTP and all data stored there")
|
||||
|
||||
onClicked: {
|
||||
questionDrawer.headerText = qsTr("Some description")
|
||||
questionDrawer.yesButtonText = qsTr("Continue")
|
||||
questionDrawer.noButtonText = qsTr("Cancel")
|
||||
|
||||
questionDrawer.yesButtonFunction = function() {
|
||||
questionDrawer.visible = false
|
||||
goToPage(PageEnum.PageDeinstalling)
|
||||
ContainersModel.removeCurrentlyProcessedContainer()
|
||||
closePage()
|
||||
closePage() //todo auto close to deinstall page?
|
||||
}
|
||||
questionDrawer.noButtonFunction = function() {
|
||||
questionDrawer.visible = false
|
||||
}
|
||||
questionDrawer.visible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QuestionDrawer {
|
||||
id: questionDrawer
|
||||
}
|
||||
}
|
||||
}
|
169
client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml
Normal file
169
client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml
Normal file
|
@ -0,0 +1,169 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import PageEnum 1.0
|
||||
import ContainerProps 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
//todo move to main?
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onInstallationErrorOccurred(errorMessage) {
|
||||
PageController.showErrorMessage(errorMessage)
|
||||
}
|
||||
|
||||
function onUpdateContainerFinished() {
|
||||
//todo change to notification
|
||||
PageController.showErrorMessage(qsTr("Settings updated successfully"))
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
|
||||
BackButtonType {
|
||||
}
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
spacing: 0
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: qsTr("Tor website settings")
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
text: qsTr("Website address")
|
||||
descriptionText: {
|
||||
var config = ContainersModel.getCurrentlyProcessedContainerConfig()
|
||||
var containerIndex = ContainersModel.getCurrentlyProcessedContainerIndex()
|
||||
return config[ContainerProps.containerTypeToString(containerIndex)]["site"]
|
||||
}
|
||||
|
||||
descriptionOnTop: true
|
||||
textColor: "#FBB26A"
|
||||
|
||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||
rightImageColor: "#D7D8DB"
|
||||
|
||||
clickedFunction: function() {
|
||||
content.copyToClipBoard(descriptionText)
|
||||
}
|
||||
}
|
||||
|
||||
TextEdit{
|
||||
id: clipboard
|
||||
visible: false
|
||||
}
|
||||
|
||||
function copyToClipBoard(text) {
|
||||
clipboard.text = text
|
||||
clipboard.selectAll()
|
||||
clipboard.copy()
|
||||
clipboard.select(0, 0)
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 40
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
textFormat: Text.RichText
|
||||
text: qsTr("Use <a href=\"https://www.torproject.org/download/\" style=\"color: #FBB26A;\">Tor Browser</a> to open this url.")
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: qsTr("After installation it takes several minutes while your onion site will become available in the Tor Network.")
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: qsTr("When configuring WordPress set the domain as this onion address.")
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 16
|
||||
Layout.leftMargin: 8
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
textColor: "#EB5757"
|
||||
|
||||
text: qsTr("Remove website")
|
||||
|
||||
onClicked: {
|
||||
questionDrawer.headerText = qsTr("Some description")
|
||||
questionDrawer.yesButtonText = qsTr("Continue")
|
||||
questionDrawer.noButtonText = qsTr("Cancel")
|
||||
|
||||
questionDrawer.yesButtonFunction = function() {
|
||||
questionDrawer.visible = false
|
||||
goToPage(PageEnum.PageDeinstalling)
|
||||
ContainersModel.removeCurrentlyProcessedContainer()
|
||||
closePage()
|
||||
closePage() //todo auto close to deinstall page?
|
||||
}
|
||||
questionDrawer.noButtonFunction = function() {
|
||||
questionDrawer.visible = false
|
||||
}
|
||||
questionDrawer.visible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QuestionDrawer {
|
||||
id: questionDrawer
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue