add tabs for multiple connections
This commit is contained in:
parent
772c1c7fa0
commit
509fe4a429
@ -660,6 +660,7 @@ void AWSClient::fetchCertificate(const QString &uuid, std::function<void(const Q
|
|||||||
request.setRawHeader("X-api-deviceId", fixedUuid.toUtf8());
|
request.setRawHeader("X-api-deviceId", fixedUuid.toUtf8());
|
||||||
request.setRawHeader("X-api-serialId", "69696969");
|
request.setRawHeader("X-api-serialId", "69696969");
|
||||||
QNetworkReply *reply = m_nam->get(request);
|
QNetworkReply *reply = m_nam->get(request);
|
||||||
|
qDebug() << "Fetching certificate for vendor:" << m_configs.at(m_usedConfigIndex).certificateVendorId << "device id:" << fixedUuid;
|
||||||
connect(reply, &QNetworkReply::finished, this, [this, reply, callback]() {
|
connect(reply, &QNetworkReply::finished, this, [this, reply, callback]() {
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
QByteArray data = reply->readAll();
|
QByteArray data = reply->readAll();
|
||||||
|
|||||||
@ -32,4 +32,6 @@ ApplicationWindow {
|
|||||||
"conductivitysensor": "green",
|
"conductivitysensor": "green",
|
||||||
"pressuresensor": "grey"
|
"pressuresensor": "grey"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property bool showConnectionTabs: false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,4 +30,7 @@ ApplicationWindow {
|
|||||||
"conductivitysensor": "green",
|
"conductivitysensor": "green",
|
||||||
"pressuresensor": "grey"
|
"pressuresensor": "grey"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property bool showConnectionTabs: false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,208 +3,279 @@ import QtQuick.Controls 2.2
|
|||||||
import QtQuick.Controls.Material 2.2
|
import QtQuick.Controls.Material 2.2
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import Nymea 1.0
|
import Nymea 1.0
|
||||||
|
import "components"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Engine {
|
|
||||||
id: engine
|
|
||||||
}
|
|
||||||
// If you need to assign to a property "engine", `engine: engine` won't work, as a workaround, use `engine: _engine`
|
|
||||||
// TODO: Improve this situation
|
|
||||||
property alias _engine: engine
|
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: engine.awsClient
|
|
||||||
property: "config"
|
|
||||||
value: settings.cloudEnvironment
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workaround flickering on pageStack animations when the white background shines through
|
// Workaround flickering on pageStack animations when the white background shines through
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Material.background
|
color: Material.background
|
||||||
}
|
}
|
||||||
|
|
||||||
StackView {
|
ListModel {
|
||||||
id: pageStack
|
id: tabModel
|
||||||
objectName: "pageStack"
|
Component.onCompleted: {
|
||||||
anchors.fill: parent
|
append({})
|
||||||
initialItem: Page {}
|
|
||||||
// onDepthChanged: {
|
|
||||||
// print("stackview depth changed", pageStack.depth)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
|
|
||||||
setupPushNotifications();
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
print("calling init. Auth required:", engine.jsonRpcClient.authenticationRequired, "initial setup required:", engine.jsonRpcClient.initialSetupRequired, "jsonrpc connected:", engine.jsonRpcClient.connected)
|
|
||||||
pageStack.clear()
|
|
||||||
if (!engine.connection.connected) {
|
|
||||||
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
function addTab() {
|
||||||
if (engine.jsonRpcClient.authenticationRequired || engine.jsonRpcClient.initialSetupRequired) {
|
|
||||||
if (engine.jsonRpcClient.pushButtonAuthAvailable) {
|
|
||||||
print("opening push button auth")
|
|
||||||
var page = pageStack.push(Qt.resolvedUrl("PushButtonAuthPage.qml"))
|
|
||||||
page.backPressed.connect(function() {
|
|
||||||
settings.lastConnectedHost = "";
|
|
||||||
engine.connection.disconnect();
|
|
||||||
init();
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
var page = pageStack.push(Qt.resolvedUrl("LoginPage.qml"));
|
|
||||||
page.backPressed.connect(function() {
|
|
||||||
settings.lastConnectedHost = "";
|
|
||||||
engine.connection.disconnect()
|
|
||||||
init();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else if (engine.jsonRpcClient.connected) {
|
|
||||||
pageStack.push(Qt.resolvedUrl("MainPage.qml"))
|
|
||||||
} else {
|
|
||||||
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleCloseEvent(close) {
|
|
||||||
if (Qt.platform.os == "android") {
|
|
||||||
// If we're connected, allow going back up to MainPage
|
|
||||||
if ((engine.jsonRpcClient.connected && pageStack.depth > 1)
|
|
||||||
// if we're not connected, only allow using the back button in wizards
|
|
||||||
|| (!engine.jsonRpcClient.connected && pageStack.depth > 3)) {
|
|
||||||
close.accepted = false;
|
|
||||||
pageStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupPushNotifications(askForPermissions) {
|
|
||||||
if (askForPermissions === undefined) {
|
|
||||||
askForPermissions = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!engine.awsClient.isLoggedIn) {
|
|
||||||
print("AWS not logged in. Cannot register for push");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PushNotifications.token.length === 0) {
|
|
||||||
print("Don't have a token yet. Cannot register for push");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PlatformHelper.hasPermissions) {
|
|
||||||
if (askForPermissions) {
|
|
||||||
PlatformHelper.requestPermissions();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
engine.awsClient.registerPushNotificationEndpoint(PushNotifications.token, PlatformHelper.deviceManufacturer + " " + PlatformHelper.deviceModel, PlatformHelper.deviceSerial + "+io.guh.nymeaapp");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: engine.jsonRpcClient
|
|
||||||
onConnectedChanged: {
|
|
||||||
print("json client connected changed", engine.jsonRpcClient.connected)
|
|
||||||
if (engine.jsonRpcClient.connected) {
|
|
||||||
settings.lastConnectedHost = engine.connection.url
|
|
||||||
}
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
onAuthenticationRequiredChanged: {
|
|
||||||
print("auth required changed")
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
onInitialSetupRequiredChanged: {
|
|
||||||
print("setup required changed")
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
onInvalidProtocolVersion: {
|
|
||||||
var popup = invalidVersionComponent.createObject(app.contentItem);
|
|
||||||
popup.actualVersion = actualVersion;
|
|
||||||
popup.minimumVersion = minimumVersion
|
|
||||||
popup.open()
|
|
||||||
settings.lastConnectedHost = ""
|
settings.lastConnectedHost = ""
|
||||||
|
tabModel.append({})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
ColumnLayout {
|
||||||
target: Qt.application
|
anchors.fill: parent
|
||||||
enabled: engine.jsonRpcClient.connected && settings.returnToHome
|
|
||||||
onStateChanged: {
|
SwipeView {
|
||||||
print("App active state changed:", state)
|
id: swipeView
|
||||||
if (state !== Qt.ApplicationActive) {
|
Layout.fillHeight: true
|
||||||
init();
|
Layout.fillWidth: true
|
||||||
|
interactive: false
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: mainRepeater
|
||||||
|
model: tabModel
|
||||||
|
|
||||||
|
delegate: StackView {
|
||||||
|
id: pageStack
|
||||||
|
height: swipeView.height
|
||||||
|
width: swipeView.width
|
||||||
|
objectName: "pageStack"
|
||||||
|
initialItem: Page {}
|
||||||
|
|
||||||
|
Engine {
|
||||||
|
id: engine
|
||||||
|
}
|
||||||
|
property alias _engine: engine
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
|
||||||
|
setupPushNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
print("calling init. Auth required:", engine.jsonRpcClient.authenticationRequired, "initial setup required:", engine.jsonRpcClient.initialSetupRequired, "jsonrpc connected:", engine.jsonRpcClient.connected)
|
||||||
|
pageStack.clear()
|
||||||
|
if (!engine.connection.connected) {
|
||||||
|
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.jsonRpcClient.authenticationRequired || engine.jsonRpcClient.initialSetupRequired) {
|
||||||
|
if (engine.jsonRpcClient.pushButtonAuthAvailable) {
|
||||||
|
print("opening push button auth")
|
||||||
|
var page = pageStack.push(Qt.resolvedUrl("PushButtonAuthPage.qml"))
|
||||||
|
page.backPressed.connect(function() {
|
||||||
|
settings.lastConnectedHost = "";
|
||||||
|
engine.connection.disconnect();
|
||||||
|
init();
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
var page = pageStack.push(Qt.resolvedUrl("LoginPage.qml"));
|
||||||
|
page.backPressed.connect(function() {
|
||||||
|
settings.lastConnectedHost = "";
|
||||||
|
engine.connection.disconnect()
|
||||||
|
init();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (engine.jsonRpcClient.connected) {
|
||||||
|
pageStack.push(Qt.resolvedUrl("MainPage.qml"))
|
||||||
|
} else {
|
||||||
|
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCloseEvent(close) {
|
||||||
|
if (Qt.platform.os == "android") {
|
||||||
|
// If we're connected, allow going back up to MainPage
|
||||||
|
if ((engine.jsonRpcClient.connected && pageStack.depth > 1)
|
||||||
|
// if we're not connected, only allow using the back button in wizards
|
||||||
|
|| (!engine.jsonRpcClient.connected && pageStack.depth > 3)) {
|
||||||
|
close.accepted = false;
|
||||||
|
pageStack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupPushNotifications(askForPermissions) {
|
||||||
|
if (askForPermissions === undefined) {
|
||||||
|
askForPermissions = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!engine.awsClient.isLoggedIn) {
|
||||||
|
print("AWS not logged in. Cannot register for push");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PushNotifications.token.length === 0) {
|
||||||
|
print("Don't have a token yet. Cannot register for push");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PlatformHelper.hasPermissions) {
|
||||||
|
if (askForPermissions) {
|
||||||
|
PlatformHelper.requestPermissions();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
engine.awsClient.registerPushNotificationEndpoint(PushNotifications.token, PlatformHelper.deviceManufacturer + " " + PlatformHelper.deviceModel, PlatformHelper.deviceSerial + "+io.guh.nymeaapp");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: engine.jsonRpcClient
|
||||||
|
onConnectedChanged: {
|
||||||
|
print("json client connected changed", engine.jsonRpcClient.connected)
|
||||||
|
if (engine.jsonRpcClient.connected) {
|
||||||
|
settings.lastConnectedHost = engine.connection.url
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
onAuthenticationRequiredChanged: {
|
||||||
|
print("auth required changed")
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
onInitialSetupRequiredChanged: {
|
||||||
|
print("setup required changed")
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
onInvalidProtocolVersion: {
|
||||||
|
var popup = invalidVersionComponent.createObject(app.contentItem);
|
||||||
|
popup.actualVersion = actualVersion;
|
||||||
|
popup.minimumVersion = minimumVersion
|
||||||
|
popup.open()
|
||||||
|
settings.lastConnectedHost = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Qt.application
|
||||||
|
enabled: engine.jsonRpcClient.connected && settings.returnToHome
|
||||||
|
onStateChanged: {
|
||||||
|
print("App active state changed:", state)
|
||||||
|
if (state !== Qt.ApplicationActive) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: PlatformHelper
|
||||||
|
onHasPermissionsChanged: {
|
||||||
|
setupPushNotifications(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: PushNotifications
|
||||||
|
onTokenChanged: {
|
||||||
|
setupPushNotifications();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: engine.awsClient
|
||||||
|
onIsLoggedInChanged: {
|
||||||
|
setupPushNotifications()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: invalidVersionComponent
|
||||||
|
Popup {
|
||||||
|
id: popup
|
||||||
|
|
||||||
|
property string actualVersion: "0.0"
|
||||||
|
property string minimumVersion: "1.0"
|
||||||
|
|
||||||
|
width: app.width * .8
|
||||||
|
height: col.childrenRect.height + app.margins * 2
|
||||||
|
x: (app.width - width) / 2
|
||||||
|
y: (app.height - height) / 2
|
||||||
|
visible: false
|
||||||
|
ColumnLayout {
|
||||||
|
id: col
|
||||||
|
anchors { left: parent.left; right: parent.right }
|
||||||
|
spacing: app.margins
|
||||||
|
Label {
|
||||||
|
text: qsTr("Connection error")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: app.largeFont
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: qsTr("Sorry, the version of the %1 box you are trying to connect to is too old. This app requires at least version %2 but the %1 box only supports %3").arg(app.systemName).arg(popup.minimumVersion).arg(popup.actualVersion)
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("OK")
|
||||||
|
onClicked: {
|
||||||
|
engine.connection.disconnect();
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
RowLayout {
|
||||||
target: PlatformHelper
|
visible: app.showConnectionTabs
|
||||||
onHasPermissionsChanged: {
|
|
||||||
setupPushNotifications(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
TabBar {
|
||||||
target: PushNotifications
|
id: tabbar
|
||||||
onTokenChanged: {
|
Layout.fillWidth: true
|
||||||
setupPushNotifications();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Repeater {
|
||||||
target: engine.awsClient
|
model: mainRepeater.count
|
||||||
onIsLoggedInChanged: {
|
|
||||||
setupPushNotifications()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
delegate: TabButton {
|
||||||
id: invalidVersionComponent
|
id: hostTabButton
|
||||||
Popup {
|
property var engine: mainRepeater.itemAt(index)._engine
|
||||||
id: popup
|
property string serverName: engine.basicConfiguration.serverName
|
||||||
|
|
||||||
property string actualVersion: "0.0"
|
contentItem: RowLayout {
|
||||||
property string minimumVersion: "1.0"
|
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.remove(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
width: app.width * .8
|
onClicked: {
|
||||||
height: col.childrenRect.height + app.margins * 2
|
swipeView.currentIndex = index
|
||||||
x: (app.width - width) / 2
|
}
|
||||||
y: (app.height - height) / 2
|
|
||||||
visible: false
|
|
||||||
ColumnLayout {
|
|
||||||
id: col
|
|
||||||
anchors { left: parent.left; right: parent.right }
|
|
||||||
spacing: app.margins
|
|
||||||
Label {
|
|
||||||
text: qsTr("Connection error")
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pixelSize: app.largeFont
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
text: qsTr("Sorry, the version of the %1 box you are trying to connect to is too old. This app requires at least version %2 but the %1 box only supports %3").arg(app.systemName).arg(popup.minimumVersion).arg(popup.actualVersion)
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("OK")
|
|
||||||
onClicked: {
|
|
||||||
engine.connection.disconnect();
|
|
||||||
popup.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TabButton {
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
contentItem: ColorIcon {
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width
|
||||||
|
name: "../images/add.svg"
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
tabModel.addTab()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,8 @@ ToolBar {
|
|||||||
property string title
|
property string title
|
||||||
property alias model: menuRepeater.model
|
property alias model: menuRepeater.model
|
||||||
|
|
||||||
|
property bool showNewTabButton: false
|
||||||
|
|
||||||
signal clicked(int index);
|
signal clicked(int index);
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
|
|||||||
Reference in New Issue
Block a user