Adjust main menu to fit better with new connection setup

This commit is contained in:
Michael Zanetti 2021-07-06 00:42:33 +02:00
parent fe0f8fee00
commit 5456384711
15 changed files with 614 additions and 218 deletions

View File

@ -142,7 +142,14 @@ NymeaConnection::ConnectionStatus JsonRpcClient::connectionStatus() const
void JsonRpcClient::connectToHost(NymeaHost *host, Connection *connection)
{
if (m_connection->currentHost()) {
disconnect(m_connection->currentHost(), &NymeaHost::nameChanged, this, &JsonRpcClient::serverNameChanged);
}
m_connection->connectToHost(host, connection);
connect(host, &NymeaHost::nameChanged, this, &JsonRpcClient::serverNameChanged);
emit serverNameChanged();
}
void JsonRpcClient::disconnectFromHost()
@ -339,6 +346,11 @@ QString JsonRpcClient::serverUuid() const
return m_serverUuid;
}
QString JsonRpcClient::serverName() const
{
return m_connection->currentHost() ? m_connection->currentHost()->name() : "";
}
QString JsonRpcClient::serverQtVersion()
{
if (!m_serverQtVersion.isEmpty()) {

View File

@ -58,6 +58,7 @@ class JsonRpcClient : public QObject
Q_PROPERTY(QString serverVersion READ serverVersion NOTIFY handshakeReceived)
Q_PROPERTY(QString jsonRpcVersion READ jsonRpcVersion NOTIFY handshakeReceived)
Q_PROPERTY(QString serverUuid READ serverUuid NOTIFY handshakeReceived)
Q_PROPERTY(QString serverName READ serverName NOTIFY serverNameChanged)
Q_PROPERTY(QString serverQtVersion READ serverQtVersion NOTIFY serverQtVersionChanged)
Q_PROPERTY(QString serverQtBuildVersion READ serverQtBuildVersion NOTIFY serverQtVersionChanged)
Q_PROPERTY(QVariantMap certificateIssuerInfo READ certificateIssuerInfo NOTIFY currentConnectionChanged)
@ -97,6 +98,7 @@ public:
QString serverVersion() const;
QString jsonRpcVersion() const;
QString serverUuid() const;
QString serverName() const;
QString serverQtVersion();
QString serverQtBuildVersion();
QVariantMap experiences() const;
@ -137,6 +139,7 @@ signals:
void createUserFailed(const QString &error);
void cloudConnectionStateChanged();
void serverQtVersionChanged();
void serverNameChanged();
void responseReceived(const int &commandId, const QVariantMap &response);

View File

@ -0,0 +1,263 @@
#include "configuredhostsmodel.h"
#include <QSettings>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(dcApplication)
ConfiguredHostsModel::ConfiguredHostsModel(QObject *parent) : QAbstractListModel(parent)
{
QSettings settings;
settings.beginGroup("ConfiguredHosts");
foreach (const QString &childGroup, settings.childGroups()) {
settings.beginGroup(childGroup);
QUuid uuid = settings.value("uuid").toUuid();
QString cachedName = settings.value("cachedName").toString();
ConfiguredHost *host = new ConfiguredHost(uuid, this);
host->setName(cachedName);
addHost(host);
settings.endGroup();
m_currentIndex = settings.value("currentIndex", 0).toInt();
}
settings.endGroup();
// If there aren't any in the config, try migrating settings from old tab model
if (m_list.isEmpty() && settings.contains("tabCount")) {
qCInfo(dcApplication()) << "Migrating tab settings to mainmenumodel";
int tabCount = settings.value("tabCount", 0).toInt();
qCDebug(dcApplication()) << "Tab count:" << tabCount;
for (int i = 0; i < tabCount; i++) {
settings.beginGroup(QString("tabSettings%1").arg(i));
QUuid uuid = settings.value("lastConnectedHost").toUuid();
ConfiguredHost *host = new ConfiguredHost(uuid, this);
addHost(host);
settings.endGroup();
}
settings.remove("tabCount");
}
// There must be always 1 at least
if (m_list.isEmpty()) {
createHost();
}
}
int ConfiguredHostsModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_list.count();
}
QVariant ConfiguredHostsModel::data(const QModelIndex &index, int role) const
{
switch (role) {
case RoleUuid:
return m_list.at(index.row())->uuid();
case RoleName:
if (!m_list.at(index.row())->name().isEmpty()) {
return m_list.at(index.row())->name();
}
return m_list.at(index.row())->uuid();
}
return QVariant();
}
QHash<int, QByteArray> ConfiguredHostsModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(RoleUuid, "uuid");
roles.insert(RoleName, "name");
return roles;
}
ConfiguredHost *ConfiguredHostsModel::get(int index) const
{
if (index < 0 || index >= m_list.count()) {
return nullptr;
}
return m_list.at(index);
}
int ConfiguredHostsModel::currentIndex() const
{
return m_currentIndex;
}
void ConfiguredHostsModel::setCurrentIndex(int currentIndex)
{
if (m_currentIndex != currentIndex) {
m_currentIndex = currentIndex;
emit currentIndexChanged();
QSettings settings;
settings.beginGroup("ConfiguredHosts");
settings.setValue("currentIndex", currentIndex);
settings.endGroup();
}
}
ConfiguredHost *ConfiguredHostsModel::createHost()
{
ConfiguredHost *host = new ConfiguredHost();
addHost(host);
return host;
}
void ConfiguredHostsModel::removeHost(int index)
{
if (index < 0 || index >= m_list.count()) {
qCWarning(dcApplication()) << "Cannot remove connection at index" << index;
return;
}
beginRemoveRows(QModelIndex(), index, index);
m_list.takeAt(index)->deleteLater();
saveToDisk();
endRemoveRows();
emit countChanged();
if (m_list.isEmpty()) {
createHost();
}
}
int ConfiguredHostsModel::indexOf(ConfiguredHost *host) const
{
return m_list.indexOf(host);
}
void ConfiguredHostsModel::addHost(ConfiguredHost *host)
{
host->setParent(this);
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
connect(host->engine()->jsonRpcClient(), &JsonRpcClient::currentHostChanged, this, [=]{
if (host->engine()->jsonRpcClient()->currentHost()) {
host->setUuid(host->engine()->jsonRpcClient()->currentHost()->uuid());
} else {
host->setUuid(QUuid());
host->setName(QString());
}
saveToDisk();
});
connect(host->engine()->jsonRpcClient(), &JsonRpcClient::serverNameChanged, this, [=]{
host->setName(host->engine()->jsonRpcClient()->serverName());
saveToDisk();
});
connect(host, &ConfiguredHost::nameChanged, this, [=](){
QModelIndex idx = index(m_list.indexOf(host));
emit dataChanged(idx, idx, {RoleName});
});
m_list.append(host);
endInsertRows();
emit countChanged();
}
void ConfiguredHostsModel::saveToDisk()
{
QSettings settings;
settings.beginGroup("ConfiguredHosts");
settings.remove("");
for (int i = 0; i < m_list.count(); i++) {
settings.beginGroup(QString::number(i));
settings.setValue("uuid", m_list.at(i)->uuid());
settings.setValue("cachedName", m_list.at(i)->name());
settings.endGroup();
}
settings.endGroup();
}
ConfiguredHost::ConfiguredHost(const QUuid &uuid, QObject *parent):
QObject(parent),
m_uuid(uuid),
m_engine(new Engine(this))
{
}
QUuid ConfiguredHost::uuid() const
{
return m_uuid;
}
void ConfiguredHost::setUuid(const QUuid &uuid)
{
if (m_uuid != uuid) {
m_uuid = uuid;
emit uuidChanged();
}
}
Engine *ConfiguredHost::engine() const
{
return m_engine;
}
QString ConfiguredHost::name() const
{
return m_name;
}
void ConfiguredHost::setName(const QString &name)
{
if (m_name != name) {
m_name = name;
emit nameChanged();
}
}
ConfiguredHostsProxyModel::ConfiguredHostsProxyModel(QObject *parent):
QSortFilterProxyModel(parent)
{
}
ConfiguredHostsModel *ConfiguredHostsProxyModel::model() const
{
return m_model;
}
void ConfiguredHostsProxyModel::setModel(ConfiguredHostsModel *model)
{
if (m_model != model) {
m_model = model;
emit modelChanged();
setSourceModel(model);
sort(0);
}
}
QUuid ConfiguredHostsProxyModel::currentHost() const
{
return m_currentHost;
}
void ConfiguredHostsProxyModel::setCurrentHost(const QUuid &currentHost)
{
if (m_currentHost != currentHost) {
m_currentHost = currentHost;
emit currentHostChanged();
invalidate();
}
}
ConfiguredHost *ConfiguredHostsProxyModel::get(int index) const
{
return m_model->get(mapToSource(this->index(index, 0)).row());
}
bool ConfiguredHostsProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
ConfiguredHost *left = m_model->get(source_left.row());
ConfiguredHost *right = m_model->get(source_right.row());
if (left->uuid() == m_currentHost) {
return true;
}
if (right->uuid() == m_currentHost) {
return false;
}
return source_left.row() < source_right.row();
}

View File

@ -0,0 +1,107 @@
#ifndef CONFIGUREDHOSTSMODEL_H
#define CONFIGUREDHOSTSMODEL_H
#include <QAbstractListModel>
#include <QSortFilterProxyModel>
#include <QUuid>
#include "engine.h"
class ConfiguredHost: public QObject
{
Q_OBJECT
Q_PROPERTY(QUuid uuid READ uuid WRITE setUuid NOTIFY uuidChanged)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(Engine* engine READ engine CONSTANT)
public:
ConfiguredHost(const QUuid &uuid = QUuid(), QObject *parent = nullptr);
QUuid uuid() const;
void setUuid(const QUuid &uuid);
QString name() const;
void setName(const QString &name);
Engine* engine() const;
signals:
void uuidChanged();
void nameChanged();
private:
QUuid m_uuid;
Engine *m_engine = nullptr;
QString m_name;
};
class ConfiguredHostsModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
public:
enum Roles {
RoleUuid,
RoleEngine,
RoleName,
};
Q_ENUM(Roles)
explicit ConfiguredHostsModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
int currentIndex() const;
void setCurrentIndex(int currentIndex);
Q_INVOKABLE int indexOf(ConfiguredHost *host) const;
Q_INVOKABLE ConfiguredHost* get(int index) const;
Q_INVOKABLE ConfiguredHost* createHost();
Q_INVOKABLE void removeHost(int index);
signals:
void countChanged();
void currentIndexChanged();
private:
void addHost(ConfiguredHost *host);
void saveToDisk();
private:
QList<ConfiguredHost*> m_list;
int m_currentIndex = 0;
};
class ConfiguredHostsProxyModel: public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(ConfiguredHostsModel* model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(QUuid currentHost READ currentHost WRITE setCurrentHost NOTIFY currentHostChanged)
public:
ConfiguredHostsProxyModel(QObject *parent = nullptr);
ConfiguredHostsModel* model() const;
void setModel(ConfiguredHostsModel *model);
QUuid currentHost() const;
void setCurrentHost(const QUuid &currentHost);
Q_INVOKABLE ConfiguredHost* get(int index) const;
signals:
void modelChanged();
void currentHostChanged();
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
private:
ConfiguredHostsModel *m_model = nullptr;
QUuid m_currentHost;
};
#endif // CONFIGUREDHOSTSMODEL_H

View File

@ -49,6 +49,7 @@
#include "dashboard/dashboardmodel.h"
#include "dashboard/dashboarditem.h"
#include "mouseobserver.h"
#include "configuredhostsmodel.h"
#include "../config.h"
#include "logging.h"
@ -168,6 +169,10 @@ int main(int argc, char *argv[])
qmlRegisterType<MouseObserver>("Nymea", 1, 0, "MouseObserver");
qmlRegisterType<ConfiguredHostsModel>("Nymea", 1, 0, "ConfiguredHostsModel");
qmlRegisterType<ConfiguredHostsProxyModel>("Nymea", 1, 0, "ConfiguredHostsProxyModel");
qmlRegisterUncreatableType<ConfiguredHost>("Nymea", 1, 0, "ConfiguredHost", "Get them from ConfiguredHostsModel");
#ifdef OVERLAY_QMLTYPES
registerOverlayTypes("Nymea", 1, 0);
#endif

View File

@ -1,12 +0,0 @@
#include "mainmenumodel.h"
MainMenuModel::MainMenuModel(QObject *parent) : QAbstractListModel(parent)
{
}
int MainMenuModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_list.count();
}

View File

@ -1,24 +0,0 @@
#ifndef MAINMENUMODEL_H
#define MAINMENUMODEL_H
#include <QAbstractListModel>
class MainMenuItem: public QObject
{
Q_OBJECT
};
class MainMenuModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit MainMenuModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
private:
QList<MainMenuItem*> m_list;
};
#endif // MAINMENUMODEL_H

View File

@ -19,9 +19,9 @@ PRE_TARGETDEPS += ../libnymea-app
linux:!android:PRE_TARGETDEPS += $$top_builddir/libnymea-app/libnymea-app.a
HEADERS += \
configuredhostsmodel.h \
dashboard/dashboarditem.h \
dashboard/dashboardmodel.h \
mainmenumodel.h \
mouseobserver.h \
nfchelper.h \
nfcthingactionwriter.h \
@ -34,9 +34,9 @@ HEADERS += \
ruletemplates/messages.h
SOURCES += main.cpp \
configuredhostsmodel.cpp \
dashboard/dashboarditem.cpp \
dashboard/dashboardmodel.cpp \
mainmenumodel.cpp \
mouseobserver.cpp \
nfchelper.cpp \
nfcthingactionwriter.cpp \

View File

@ -7,7 +7,8 @@ import Nymea 1.0
Drawer {
id: root
property Engine currentEngine: null
property ConfiguredHostsModel configuredHosts: null
readonly property Engine currentEngine: configuredHosts.get(configuredHosts.currentIndex).engine
signal openThingSettings();
signal openMagicSettings();
@ -17,12 +18,12 @@ Drawer {
signal startWirelessSetup();
signal startManualConnection();
signal startDemoMode();
background: Rectangle {
color: Style.backgroundColor
}
onClosed: topSectionLayout.configureConnections = false;
ColumnLayout {
anchors.fill: parent
@ -30,38 +31,88 @@ Drawer {
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: topSectionLayout.implicitHeight + app.margins * 2
Layout.preferredHeight: topSectionLayout.implicitHeight
color: Qt.tint(Style.backgroundColor, Qt.rgba(Style.foregroundColor.r, Style.foregroundColor.g, Style.foregroundColor.b, 0.05))
ColumnLayout {
id: topSectionLayout
anchors { left: parent.left; top: parent.top; right: parent.right; margins: app.margins }
spacing: app.margins
anchors { left: parent.left; top: parent.top; right: parent.right }
spacing: 0
Image {
Layout.preferredHeight: Style.hugeIconSize
sourceSize.height: Style.hugeIconSize
source: "qrc:/styles/%1/logo-wide.svg".arg(styleController.currentStyle)
}
property bool configureConnections: false
RowLayout {
visible: root.currentEngine && root.currentEngine.jsonRpcClient.currentHost
ColumnLayout {
Label {
Layout.fillWidth: true
text: root.currentEngine && root.currentEngine.jsonRpcClient.currentHost ? root.currentEngine.jsonRpcClient.currentHost.name : Configuration.systemName
}
Label {
Layout.fillWidth: true
text: root.currentEngine.jsonRpcClient.currentConnection ? root.currentEngine.jsonRpcClient.currentConnection.url : ""
font.pixelSize: app.extraSmallFont
enabled: false
}
Layout.margins: Style.margins
Image {
Layout.preferredHeight: Style.hugeIconSize
sourceSize.height: Style.hugeIconSize
Layout.fillWidth: true
fillMode: Image.PreserveAspectFit
horizontalAlignment: Image.AlignLeft
source: "qrc:/styles/%1/logo-wide.svg".arg(styleController.currentStyle)
}
ProgressButton {
imageSource: "/ui/images/configure.svg"
longpressEnabled: false
imageSource: "../images/close.svg"
Layout.alignment: Qt.AlignBottom
color: topSectionLayout.configureConnections ? Style.accentColor : Style.iconColor
onClicked: {
root.currentEngine.jsonRpcClient.disconnectFromHost();
topSectionLayout.configureConnections = !topSectionLayout.configureConnections
}
}
}
Repeater {
model: root.configuredHosts
delegate: NymeaItemDelegate {
readonly property ConfiguredHost configuredHost: root.configuredHosts.get(index)
Layout.fillWidth: true
text: model.name.length > 0 ? model.name : qsTr("New connection")
subText: configuredHost.engine.jsonRpcClient.currentConnection ? configuredHost.engine.jsonRpcClient.currentConnection.url : ""
prominentSubText: false
progressive: false
additionalItem: RowLayout {
anchors.verticalCenter: parent.verticalCenter
Rectangle {
height: Style.smallIconSize
width: height
radius: height / 2
color: Style.accentColor
Layout.alignment: Qt.AlignVCenter
visible: index === configuredHostsModel.currentIndex && !topSectionLayout.configureConnections
}
ProgressButton {
imageSource: "/ui/images/close.svg"
visible: topSectionLayout.configureConnections
longpressEnabled: false
onClicked: {
configuredHostsModel.removeHost(index)
}
}
}
onClicked: {
configuredHostsModel.currentIndex = index
root.close()
}
}
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: topSectionLayout.configureConnections ? childrenRect.height : 0
Behavior on Layout.preferredHeight { NumberAnimation { duration: Style.animationDuration; easing.type: Easing.InOutQuad }}
clip: true
NymeaItemDelegate {
width: parent.width
text: qsTr("Set up another...")
iconName: "add"
progressive: false
onClicked: {
var host = configuredHostsModel.createHost()
configuredHostsModel.currentIndex = configuredHosts.indexOf(host)
root.close();
}
}
@ -83,40 +134,6 @@ Drawer {
width: parent.width
spacing: 0
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Wireless setup")
iconName: "../images/connections/bluetooth.svg"
progressive: false
visible: root.currentEngine && root.currentEngine.jsonRpcClient.currentHost == null
onClicked: {
root.startWirelessSetup();
root.close();
}
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Manual connection")
iconName: "../images/connections/network-vpn.svg"
progressive: false
visible: root.currentEngine && root.currentEngine.jsonRpcClient.currentHost == null
onClicked: {
root.startManualConnection();
root.close();
}
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Demo mode")
iconName: "../images/private-browsing.svg"
progressive: false
visible: root.currentEngine && root.currentEngine.jsonRpcClient.currentHost == null
onClicked: {
root.startDemoMode();
root.close();
}
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Configure things")

View File

@ -81,7 +81,6 @@ ApplicationWindow {
property bool showHiddenOptions: false
property string cloudEnvironment: "Community"
property bool showConnectionTabs: false
property int tabCount: 1
// FIXME: This shouldn't be needed... we should probably only use the system locale and not even provide a setting
// However, the topic is more complex, and in the long run we'd probably want to allow the user selecting the
// desired unit for particular interfaces/things/views. See https://github.com/nymea/nymea/issues/386
@ -108,13 +107,17 @@ ApplicationWindow {
value: "cloudEnvironment" in app ? app.cloudEnvironment : settings.cloudEnvironment
}
ConfiguredHostsModel {
id: configuredHostsModel
}
property alias mainMenu: m
MainMenu {
id: m
height: app.height
width: Math.min(300, app.width)
// z: 1000
currentEngine: rootItem.currentEngine
configuredHosts: configuredHostsModel
onOpenThingSettings: rootItem.openThingSettings();
onOpenMagicSettings: rootItem.openMagicSettings();
onOpenAppSettings: rootItem.openAppSettings();
@ -122,7 +125,6 @@ ApplicationWindow {
onConfigureMainView: rootItem.configureMainView();
onStartManualConnection: rootItem.startManualConnection();
onStartWirelessSetup: rootItem.startWirelessSetup();
onStartDemoMode: rootItem.startDemoMode();
}
RootItem {

View File

@ -40,8 +40,6 @@ import "connection"
Item {
id: root
readonly property Engine currentEngine: swipeView.currentItem ? swipeView.currentItem.engine : null
function handleAndroidBackButton() {
return swipeView.currentItem.handleAndroidBackButton()
}
@ -77,53 +75,6 @@ Item {
swipeView.currentItem.pageStack.currentItem.configureViews()
}
function startManualConnection() {
d.pushSettingsPage("connection/ManualConnectPage.qml")
}
function startWirelessSetup() {
d.pushSettingsPage("connection/wifisetup/BluetoothDiscoveryPage.qml");
}
function startDemoMode() {
var host = nymeaDiscovery.nymeaHosts.createWanHost("Demo server", "nymea://nymea.nymea.io:2222")
root.currentEngine.jsonRpcClient.connectToHost(host)
}
ListModel {
id: tabModel
Component.onCompleted: {
for (var i = 0; i < settings.tabCount; i++) {
tabModel.append({})
}
}
function addTab() {
tabModel.append({})
settings.tabCount++;
swipeView.currentIndex = settings.tabCount - 1
tabbar.currentIndex = swipeView.currentIndex
}
function removeTab(index) {
if (swipeView.currentIndex === index) {
if (swipeView.currentIndex > 0) {
swipeView.currentIndex--;
} else {
swipeView.currentIndex++;
}
}
remove(index);
settings.tabCount--;
tabbar.currentIndex = swipeView.currentIndex
orphanedSettings.lastConnectedHost = ""
}
}
Settings {
id: orphanedSettings
category: "tabSettings" + tabModel.count
property string lastConnectedHost
}
ColumnLayout {
anchors.fill: parent
spacing: 0
@ -133,29 +84,26 @@ Item {
Layout.fillHeight: true
Layout.fillWidth: true
interactive: false
currentIndex: configuredHostsModel.currentIndex
Repeater {
id: mainRepeater
model: tabModel
model: configuredHostsModel
delegate: Item {
height: swipeView.height
width: swipeView.width
clip: true
readonly property ConfiguredHost configuredHost: configuredHostsModel.get(index)
property var tabSettings: Settings {
category: "tabSettings" + index
property string lastConnectedHost
property int currentMainViewIndex: -1
}
Engine {
id: engineObject
}
readonly property Engine engine: engineObject
readonly property Engine _engine: engineObject // In case a child cannot use "engine"
property int connectionTabIndex: index
// onConnectionTabIndexChanged: tabSettings.lastConnectedHost = engine.jsonRpcClient.url
readonly property Engine engine: configuredHost.engine
readonly property Engine _engine: configuredHost.engine // In case a child cannot use "engine"
Binding {
target: nymeaDiscovery
@ -173,9 +121,9 @@ Item {
Component.onCompleted: {
setupPushNotifications();
if (tabSettings.lastConnectedHost.length > 0) {
print("Last connected host was", tabSettings.lastConnectedHost)
var cachedHost = nymeaDiscovery.nymeaHosts.find(tabSettings.lastConnectedHost);
if (configuredHost.uuid.toString() !== "{00000000-0000-0000-0000-000000000000}") {
print("Configured host id is", configuredHost.uuid)
var cachedHost = nymeaDiscovery.nymeaHosts.find(configuredHost.uuid);
if (cachedHost) {
engine.jsonRpcClient.connectToHost(cachedHost)
return;
@ -201,7 +149,6 @@ Item {
pageStack.clear()
if (!engine.jsonRpcClient.currentHost) {
print("pushing ConnectPage")
tabSettings.lastConnectedHost = ""
pageStack.push(Configuration.connectionWizard)
PlatformHelper.hideSplashScreen();
return;
@ -213,7 +160,7 @@ Item {
print("opening push button auth")
var page = pageStack.push(Qt.resolvedUrl("PushButtonAuthPage.qml"))
page.backPressed.connect(function() {
tabSettings.lastConnectedHost = "";
// tabSettings.lastConnectedHost = "";
engine.jsonRpcClient.disconnectFromHost();
init();
})
@ -222,7 +169,7 @@ Item {
if (engine.jsonRpcClient.initialSetupRequired) {
var page = pageStack.push(Qt.resolvedUrl("connection/SetupWizard.qml"));
page.backPressed.connect(function() {
tabSettings.lastConnectedHost = "";
// tabSettings.lastConnectedHost = "";
engine.jsonRpcClient.disconnectFromHost()
init();
})
@ -231,7 +178,7 @@ Item {
var page = pageStack.push(Qt.resolvedUrl("connection/LoginPage.qml"));
page.backPressed.connect(function() {
tabSettings.lastConnectedHost = "";
// tabSettings.lastConnectedHost = "";
engine.jsonRpcClient.disconnectFromHost()
init();
})
@ -240,6 +187,7 @@ Item {
}
if (engine.jsonRpcClient.connected) {
print("Connected to", engine.jsonRpcClient.currentHost.uuid, engine.jsonRpcClient.currentHost.name)
pageStack.push(Qt.resolvedUrl("MainPage.qml"))
return;
}
@ -350,7 +298,8 @@ Item {
print("json client connected changed", engine.jsonRpcClient.connected)
if (engine.jsonRpcClient.connected) {
nymeaDiscovery.cacheHost(engine.jsonRpcClient.currentHost)
tabSettings.lastConnectedHost = engine.jsonRpcClient.serverUuid
configuredHost.uuid = engine.jsonRpcClient.serverUuid
// tabSettings.lastConnectedHost = engine.jsonRpcClient.serverUuid
}
init();
}
@ -369,14 +318,14 @@ Item {
popup.actualVersion = actualVersion;
popup.minVersion = minVersion;
popup.open()
tabSettings.lastConnectedHost = ""
// tabSettings.lastConnectedHost = ""
}
onInvalidMaximumVersion: {
var popup = invalidVersionComponent.createObject(app.contentItem);
popup.actualVersion = actualVersion;
popup.maxVersion = maxVersion;
popup.open()
tabSettings.lastConnectedHost = ""
// tabSettings.lastConnectedHost = ""
}
}
@ -477,16 +426,16 @@ Item {
Layout.fillWidth: true
Material.elevation: 2
position: TabBar.Footer
currentIndex: configuredHostsModel.currentIndex
Repeater {
model: tabModel.count
model: configuredHostsModel
delegate: TabButton {
id: hostTabButton
property var engine: mainRepeater.itemAt(index)._engine
property string serverName: engine.nymeaConfiguration.serverName
readonly property ConfiguredHost configuredHost: configuredHostsModel.get(index)
Material.elevation: index
width: Math.max(150, tabbar.width / tabModel.count)
width: Math.max(150, tabbar.width / configuredHostsModel.count)
Rectangle {
anchors.fill: parent
@ -494,49 +443,19 @@ Item {
opacity: 0.06
}
contentItem: RowLayout {
Label {
Layout.fillWidth: true
text: hostTabButton.serverName !== "" ? hostTabButton.serverName : qsTr("New connection")
elide: Text.ElideRight
}
ColorIcon {
Layout.fillHeight: true
Layout.preferredWidth: height
visible: tabModel.count > 1
name: "../images/close.svg"
MouseArea {
anchors.fill: parent
onClicked: tabModel.removeTab(index)
}
}
contentItem: Label {
Layout.fillWidth: true
text: hostTabButton.configuredHost.name !== "" ? hostTabButton.configuredHost.name : qsTr("New connection")
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
onClicked: {
swipeView.currentIndex = index
configuredHostsModel.currentIndex = index
}
}
}
}
Pane {
Layout.preferredHeight: tabbar.height
Layout.preferredWidth: height
Material.elevation: 2
padding: 0
TabButton {
anchors.fill: parent
contentItem: ColorIcon {
height: parent.height
width: parent.width
name: "../images/tab-new.svg"
}
onClicked: {
tabModel.addTab()
}
}
}
}
}
}

View File

@ -98,4 +98,8 @@ Item {
readonly property color red: "#952727"
readonly property color white: "white"
readonly property int fastAnimationDuration: 100
readonly property int animationDuration: 150
readonly property int slowAnimationDuration: 300
}

View File

@ -65,9 +65,7 @@ Item {
buttonDelegate.longpressed = false
}
onReleased: {
print("onReleased!")
if (!containsMouse) {
print("cancelled")
buttonDelegate.longpressed = false;
return;
}
@ -80,7 +78,6 @@ Item {
root.clicked();
}
buttonDelegate.longpressed = false
print("released end")
}
}

View File

@ -25,15 +25,28 @@ Page {
anchors.fill: parent
spacing: Style.margins
Label {
id: titleLabel
Layout.fillWidth: true
Layout.margins: Style.margins
text: root.title
font: Style.largeFont
horizontalAlignment: Text.AlignHCenter
RowLayout {
ProgressButton {
imageSource: "/ui/images/navigation-menu.svg"
longpressEnabled: false
onClicked: mainMenu.open()
}
Label {
id: titleLabel
Layout.fillWidth: true
Layout.margins: Style.margins
text: root.title
font: Style.largeFont
horizontalAlignment: Text.AlignHCenter
}
Item {
Layout.preferredHeight: Style.iconSize + Style.smallMargins * 2
Layout.preferredWidth: Style.iconSize + Style.smallMargins * 2
}
}
Label {
id: textLabel
Layout.fillWidth: true

View File

@ -146,7 +146,8 @@ WizardPageBase {
WizardPageBase {
title: qsTr("Connection")
text: qsTr("Connecting to the nymea system.")
showNextButton: false
nextButtonText: qsTr("Manual connection")
onNext: pageStack.push(manualConnectionComponent)
onBack: pageStack.pop()
@ -248,6 +249,95 @@ WizardPageBase {
}
}
Component {
id: manualConnectionComponent
WizardPageBase {
title: qsTr("Manual connection")
text: qsTr("Please enter the connection information for your nymea system")
onBack: pageStack.pop()
onNext: {
var rpcUrl
var hostAddress
var port
// Set default to placeholder
if (addressTextInput.text === "") {
hostAddress = addressTextInput.placeholderText
} else {
hostAddress = addressTextInput.text
}
if (portTextInput.text === "") {
port = portTextInput.placeholderText
} else {
port = portTextInput.text
}
if (connectionTypeComboBox.currentIndex == 0) {
if (secureCheckBox.checked) {
rpcUrl = "nymeas://" + hostAddress + ":" + port
} else {
rpcUrl = "nymea://" + hostAddress + ":" + port
}
} else if (connectionTypeComboBox.currentIndex == 1) {
if (secureCheckBox.checked) {
rpcUrl = "wss://" + hostAddress + ":" + port
} else {
rpcUrl = "ws://" + hostAddress + ":" + port
}
}
print("Try to connect ", rpcUrl)
var host = nymeaDiscovery.nymeaHosts.createWanHost("Manual connection", rpcUrl);
engine.jsonRpcClient.connectToHost(host)
}
content: ColumnLayout {
anchors.fill: parent
anchors.margins: Style.margins
GridLayout {
columns: 2
Label {
text: qsTr("Protocol")
}
ComboBox {
id: connectionTypeComboBox
Layout.fillWidth: true
model: [ qsTr("TCP"), qsTr("Websocket") ]
}
Label { text: qsTr("Address:") }
TextField {
id: addressTextInput
objectName: "addressTextInput"
Layout.fillWidth: true
placeholderText: "127.0.0.1"
}
Label { text: qsTr("Port:") }
TextField {
id: portTextInput
Layout.fillWidth: true
placeholderText: connectionTypeComboBox.currentIndex === 0 ? "2222" : "4444"
validator: IntValidator{bottom: 1; top: 65535;}
}
Label {
Layout.fillWidth: true
text: qsTr("Encrypted connection:")
}
CheckBox {
id: secureCheckBox
checked: true
}
}
}
}
}
Component {
id: wiredInstructionsComponent
WizardPageBase {