This repository has been archived on 2026-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
2018-09-19 13:03:46 +02:00

414 lines
14 KiB
QML

import QtQuick 2.8
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.2
import Qt.labs.settings 1.0
import QtQuick.Window 2.3
import Nymea 1.0
//import QtFirebase 1.0
ApplicationWindow {
id: app
visible: true
width: 360
height: 580
visibility: ApplicationWindow.AutomaticVisibility
font: Qt.application.font
// Those variables must be present in the Style
title: appName
Material.primary: primaryColor
Material.accent: accentColor
Material.foreground: foregroundColor
property int margins: 14
property int bigMargins: 20
property int extraSmallFont: 10
property int smallFont: 13
property int mediumFont: 16
property int largeFont: 20
property int iconSize: 30
property int delegateHeight: 60
readonly property bool landscape: app.width > app.height
readonly property var settings: Settings {
property string lastConnectedHost: ""
property alias viewMode: app.visibility
property bool returnToHome: false
property bool darkTheme: false
property string graphStyle: "bars"
property string style: "light"
property int currentMainViewIndex: 0
property bool showHiddenOptions: false
property int cloudEnvironment: 0
}
Binding {
target: Engine.awsClient
property: "config"
value: settings.cloudEnvironment
}
Component.onCompleted: {
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
setupPushNotifications();
}
Connections {
target: PlatformHelper
onHasPermissionsChanged: {
setupPushNotifications(false)
}
}
Connections {
target: Engine.awsClient
onIsLoggedInChanged: {
setupPushNotifications()
}
}
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 = ""
}
}
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 setupPushNotifications(askForPermissions) {
if (askForPermissions === undefined) {
askForPermissions = true;
}
if (Engine.awsClient.isLoggedIn) {
if (!PlatformHelper.hasPermissions) {
if (askForPermissions) {
PlatformHelper.requestPermissions();
}
} else {
Engine.awsClient.registerPushNotificationEndpoint(PushNotifications.token, PlatformHelper.deviceManufacturer + " " + PlatformHelper.deviceModel, PlatformHelper.deviceSerial);
}
}
}
// Workaround flickering on pageStack animations when the white background shines through
Rectangle {
anchors.fill: parent
color: Material.background
}
StackView {
id: pageStack
objectName: "pageStack"
anchors.fill: parent
initialItem: Page {}
// onDepthChanged: {
// print("stackview depth changed", pageStack.depth)
// }
}
onClosing: {
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();
}
}
}
Connections {
target: Qt.application
enabled: Engine.jsonRpcClient.connected && settings.returnToHome
onStateChanged: {
print("App active state changed:", state)
if (state !== Qt.ApplicationActive) {
init();
}
}
}
property var supportedInterfaces: ["light", "weather", "sensor", "media", "garagegate", "extendedawning", "extendedshutter", "extendedblind", "button", "notifications", "inputtrigger", "outputtrigger", "gateway"]
function interfaceToString(name) {
switch(name) {
case "light":
return qsTr("Lighting")
case "weather":
return qsTr("Weather")
case "sensor":
return qsTr("Sensors")
case "media":
return qsTr("Media")
case "button":
return qsTr("Switches")
case "gateway":
return qsTr("Gateways")
case "notifications":
return qsTr("Notifications")
case "temperaturesensor":
return qsTr("Temperature");
case "humiditysensor":
return qsTr("Humidity");
case "pressuresensor":
return qsTr("Pressure");
case "inputtrigger":
return qsTr("Incoming Events");
case "outputtrigger":
return qsTr("Events");
case "shutter":
case "extendedshutter":
return qsTr("Shutters");
case "blind":
case "extendedblind":
return qsTr("Blinds");
case "awning":
case "extendedawning":
return qsTr("Awnings");
case "garagegate":
return qsTr("Garage gates");
case "uncategorized":
return qsTr("Uncategorized")
}
}
function interfacesToIcon(interfaces) {
for (var i = 0; i < interfaces.length; i++) {
var icon = interfaceToIcon(interfaces[i]);
if (icon !== "") {
return icon;
}
}
return Qt.resolvedUrl("images/select-none.svg")
}
function interfaceToIcon(name) {
switch (name) {
case "light":
case "colorlight":
case "dimmablelight":
return Qt.resolvedUrl("images/light-on.svg")
case "sensor":
return Qt.resolvedUrl("images/sensors.svg")
case "temperaturesensor":
return Qt.resolvedUrl("images/sensors/temperature.svg")
case "humiditysensor":
return Qt.resolvedUrl("images/sensors/humidity.svg")
case "moisturesensor":
return Qt.resolvedUrl("images/sensors/moisture.svg")
case "lightsensor":
return Qt.resolvedUrl("images/sensors/light.svg")
case "conductivitysensor":
return Qt.resolvedUrl("images/sensors/conductivity.svg")
case "pressuresensor":
return Qt.resolvedUrl("images/sensors/pressure.svg")
case "media":
case "mediacontroller":
return Qt.resolvedUrl("images/mediaplayer-app-symbolic.svg")
case "button":
case "longpressbutton":
case "simplemultibutton":
case "longpressmultibutton":
return Qt.resolvedUrl("images/system-shutdown.svg")
case "weather":
return Qt.resolvedUrl("images/weather-app-symbolic.svg")
case "temperaturesensor":
return Qt.resolvedUrl("images/sensors/temperature.svg")
case "humiditysensor":
return Qt.resolvedUrl("images/sensors/humidity.svg")
case "gateway":
return Qt.resolvedUrl("images/network-wired-symbolic.svg")
case "notifications":
return Qt.resolvedUrl("images/notification.svg")
case "connectable":
return Qt.resolvedUrl("images/stock_link.svg")
case "inputtrigger":
return Qt.resolvedUrl("images/attention.svg")
case "outputtrigger":
return Qt.resolvedUrl("images/send.svg")
case "shutter":
case "extendedshutter":
return Qt.resolvedUrl("images/DeviceIconRollerShutter.svg")
case "blind":
case "extendedblind":
return Qt.resolvedUrl("images/DeviceIconBlind.svg")
case "garagegate":
return Qt.resolvedUrl("images/shutter/shutter-100.svg")
case "extendedawning":
return Qt.resolvedUrl("images/awning/awning-100.svg")
case "battery":
return Qt.resolvedUrl("images/battery/battery-050.svg")
case "uncategorized":
return Qt.resolvedUrl("images/select-none.svg")
case "simpleclosable":
return Qt.resolvedUrl("images/sort-listitem.svg")
default:
console.warn("InterfaceToIcon: Unhandled interface", name)
}
return "";
}
property var fallbackColors: {
"temperaturesensor": "red",
"humiditysensor": "deepskyblue",
"moisturesensor":"blue",
"lightsensor": "orange",
"conductivitysensor": "green",
"pressuresensor": "grey"
}
function interfaceToColor(name) {
// Try to load color map from style
if (interfaceColors[name]) {
return interfaceColors[name];
}
if (fallbackColors[name]) {
return fallbackColors[name];
}
return "grey";
}
function interfaceToDisplayName(name) {
switch (name) {
case "light":
return qsTr("light")
case "button":
return "button";
case "sensor":
return qsTr("sensor")
}
}
function interfaceListToDevicePage(interfaceList) {
var page;
if (interfaceList.indexOf("media") >= 0) {
page = "MediaDevicePage.qml";
} else if (interfaceList.indexOf("button") >= 0) {
page = "ButtonDevicePage.qml";
} else if (interfaceList.indexOf("weather") >= 0) {
page = "WeatherDevicePage.qml";
} else if (interfaceList.indexOf("sensor") >= 0) {
page = "SensorDevicePage.qml";
} else if (interfaceList.indexOf("inputtrigger") >= 0) {
page = "InputTriggerDevicePage.qml";
} else if (interfaceList.indexOf("garagegate") >= 0 ) {
page = "GarageGateDevicePage.qml";
} else if (interfaceList.indexOf("light") >= 0) {
page = "ColorLightDevicePage.qml";
} else if (interfaceList.indexOf("extendedshutter") >= 0 ) {
page = "ShutterDevicePage.qml";
} else if (interfaceList.indexOf("extendedawning") >= 0) {
page = "AwningDevicePage.qml";
} else {
page = "GenericDevicePage.qml";
}
print("Selecting page", page, "for interface list:", interfaceList)
return page;
}
function pad(num, size) {
var s = "000000000" + num;
return s.substr(s.length-size);
}
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()
}
}
}
}
}
KeyboardLoader {
id: keyboardRect
anchors { left: parent.left; bottom: parent.bottom; right: parent.right }
}
}