diff --git a/lib/main.dart b/lib/main.dart index 972c831..d31aab7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -105,6 +105,7 @@ part 'pages/widgets/page_loading_indicator.dart'; part 'pages/widgets/page_loading_error.dart'; part 'pages/panel.page.dart'; part 'pages/main.page.dart'; +part 'pages/integration_settings.page.dart'; part 'home_assistant.class.dart'; part 'pages/log.page.dart'; part 'pages/entity.page.dart'; @@ -140,7 +141,7 @@ final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin(); const String appName = "HA Client"; const appVersionNumber = "0.7.0"; -const appVersionAdd = "alpha3"; +const appVersionAdd = "alpha1"; const appVersion = "$appVersionNumber-$appVersionAdd"; void main() async { @@ -181,6 +182,7 @@ class HAClientApp extends StatelessWidget { routes: { "/": (context) => MainPage(title: 'HA Client'), "/connection-settings": (context) => ConnectionSettingsPage(title: "Settings"), + "/integration-settings": (context) => IntegrationSettingsPage(title: "Integration settings"), "/putchase": (context) => PurchasePage(title: "Support app development"), "/play-media": (context) => PlayMediaPage( mediaUrl: "${ModalRoute.of(context).settings.arguments != null ? (ModalRoute.of(context).settings.arguments as Map)['url'] : ''}", diff --git a/lib/managers/mobile_app_integration_manager.class.dart b/lib/managers/mobile_app_integration_manager.class.dart index da6577a..e0b5e08 100644 --- a/lib/managers/mobile_app_integration_manager.class.dart +++ b/lib/managers/mobile_app_integration_manager.class.dart @@ -4,18 +4,20 @@ class MobileAppIntegrationManager { static final _appRegistrationData = { "app_version": "$appVersion", - "device_name": "${HomeAssistant().userName}'s ${DeviceInfoManager().model}", + "device_name": "", "manufacturer": DeviceInfoManager().manufacturer, "model": DeviceInfoManager().model, "os_version": DeviceInfoManager().osVersion, "app_data": { - "push_token": "${HomeAssistant().fcmToken}", + "push_token": "", "push_url": "https://us-central1-ha-client-c73c4.cloudfunctions.net/sendPushNotification" } }; static Future checkAppRegistration({bool forceRegister: false, bool showOkDialog: false}) { Completer completer = Completer(); + _appRegistrationData["device_name"] = "${HomeAssistant().userName}'s ${DeviceInfoManager().model}"; + (_appRegistrationData["app_data"] as Map)["push_token"] = "${HomeAssistant().fcmToken}"; if (ConnectionManager().webhookId == null || forceRegister) { Logger.d("Mobile app was not registered yet or need to be reseted. Registering..."); var registrationData = Map.from(_appRegistrationData); @@ -35,6 +37,7 @@ class MobileAppIntegrationManager { SharedPreferences.getInstance().then((prefs) { prefs.setString("app-webhook-id", responseObject["webhook_id"]); ConnectionManager().webhookId = responseObject["webhook_id"]; + completer.complete(); eventBus.fire(ShowPopupDialogEvent( title: "Mobile app Integration was created", diff --git a/lib/pages/integration_settings.page.dart b/lib/pages/integration_settings.page.dart new file mode 100644 index 0000000..41216ca --- /dev/null +++ b/lib/pages/integration_settings.page.dart @@ -0,0 +1,176 @@ +part of '../main.dart'; + +class IntegrationSettingsPage extends StatefulWidget { + IntegrationSettingsPage({Key key, this.title}) : super(key: key); + + final String title; + + @override + _IntegrationSettingsPageState createState() => new _IntegrationSettingsPageState(); +} + +class _IntegrationSettingsPageState extends State { + + int _locationInterval = LocationManager().defaultUpdateIntervalMinutes; + bool _locationTrackingEnabled = false; + + @override + void initState() { + super.initState(); + _loadSettings(); + + } + + _loadSettings() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.reload(); + SharedPreferences.getInstance().then((prefs) { + setState(() { + _locationTrackingEnabled = prefs.getBool("location-enabled") ?? false; + _locationInterval = prefs.getInt("location-interval") ?? LocationManager().defaultUpdateIntervalMinutes; + }); + }); + } + + void incLocationInterval() { + if (_locationInterval < 720) { + setState(() { + _locationInterval = _locationInterval + 1; + }); + } + } + + void decLocationInterval() { + if (_locationInterval > 1) { + setState(() { + _locationInterval = _locationInterval - 1; + }); + } + } + + restart() { + eventBus.fire(ShowPopupDialogEvent( + title: "Are you sure you want to restart Home Assistant?", + body: "This will restart your Home Assistant server.", + positiveText: "Sure. Make it so", + negativeText: "What?? No!", + onPositive: () { + ConnectionManager().callService(domain: "homeassistant", service: "restart", entityId: null); + }, + )); + } + + stop() { + eventBus.fire(ShowPopupDialogEvent( + title: "Are you sure you want to STOP Home Assistant?", + body: "This will STOP your Home Assistant server. It means that your web interface as well as HA Client will not work untill you'll find a way to start your server using ssh or something.", + positiveText: "Sure. Make it so", + negativeText: "What?? No!", + onPositive: () { + ConnectionManager().callService(domain: "homeassistant", service: "stop", entityId: null); + }, + )); + } + + updateRegistration() { + MobileAppIntegrationManager.checkAppRegistration(showOkDialog: true); + } + + resetRegistration() { + eventBus.fire(ShowPopupDialogEvent( + title: "Waaaait", + body: "If you don't whant to have duplicate integrations and entities in your HA for your current device, first you need to remove MobileApp integration from Integration settings in HA and restart server.", + positiveText: "Done it already", + negativeText: "Ok, I will", + onPositive: () { + MobileAppIntegrationManager.checkAppRegistration(showOkDialog: true, forceRegister: true); + }, + )); + } + + @override + Widget build(BuildContext context) { + return new Scaffold( + appBar: new AppBar( + leading: IconButton(icon: Icon(Icons.arrow_back), onPressed: (){ + Navigator.pop(context); + }), + title: new Text(widget.title), + ), + body: ListView( + scrollDirection: Axis.vertical, + padding: const EdgeInsets.all(20.0), + children: [ + Text("Location tracking", style: TextStyle(fontSize: Sizes.largeFontSize-2)), + Container(height: Sizes.rowPadding,), + Row( + children: [ + Text("Enable device location tracking"), + Switch( + value: _locationTrackingEnabled, + onChanged: (value) { + SharedPreferences.getInstance().then((prefs) => prefs.setBool("location-enabled", value)); + if (value) { + LocationManager().updateDeviceLocation(); + } + setState(() { + _locationTrackingEnabled = value; + }); + }, + ), + ], + ), + Container(height: Sizes.rowPadding,), + Text("Location update interval in minutes:"), + Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + //Expanded(child: Container(),), + FlatButton( + padding: EdgeInsets.all(0.0), + child: Text("+", style: TextStyle(fontSize: Sizes.largeFontSize)), + onPressed: () => incLocationInterval(), + ), + Text("$_locationInterval", style: TextStyle(fontSize: Sizes.largeFontSize)), + FlatButton( + padding: EdgeInsets.all(0.0), + child: Text("-", style: TextStyle(fontSize: Sizes.largeFontSize)), + onPressed: () => decLocationInterval(), + ), + ], + ), + Divider(), + Text("Registration", style: TextStyle(fontSize: Sizes.largeFontSize-2)), + Container(height: Sizes.rowPadding,), + Text("${HomeAssistant().userName}'s ${DeviceInfoManager().model}, ${DeviceInfoManager().osName} ${DeviceInfoManager().osVersion}"), + Container(height: 6.0,), + Text("Here you can manually check if HA Client integration with your Home Assistant works fine. As mobileApp integration in Home Assistant is still in development, this is not 100% correct check."), + //Divider(), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + RaisedButton( + color: Colors.blue, + onPressed: () => updateRegistration(), + child: Text("Check registration", style: TextStyle(color: Colors.white)) + ), + Container(width: 10.0,), + RaisedButton( + color: Colors.redAccent, + onPressed: () => resetRegistration(), + child: Text("Reset registration", style: TextStyle(color: Colors.white)) + ) + ], + ), + ] + ), + ); + } + + @override + void dispose() { + LocationManager().setSettings(_locationTrackingEnabled, _locationInterval); + super.dispose(); + } +} diff --git a/lib/pages/main.page.dart b/lib/pages/main.page.dart index 2e748d2..034bbe2 100644 --- a/lib/pages/main.page.dart +++ b/lib/pages/main.page.dart @@ -410,12 +410,20 @@ class _MainPageState extends ReceiveShareState with WidgetsBindingObse menuItems.addAll([ Divider(), ListTile( - leading: Icon(MaterialDesignIcons.getIconDataFromIconName("mdi:login-variant")), + leading: Icon(MaterialDesignIcons.getIconDataFromIconName("mdi:server-network")), title: Text("Connection settings"), onTap: () { Navigator.of(context).pop(); Navigator.of(context).pushNamed('/connection-settings'); }, + ), + ListTile( + leading: Icon(MaterialDesignIcons.getIconDataFromIconName("mdi:cellphone-settings-variant")), + title: Text("Integration settings"), + onTap: () { + Navigator.of(context).pop(); + Navigator.of(context).pushNamed('/integration-settings'); + }, ) ]); menuItems.addAll([ diff --git a/lib/panels/config_panel_widget.dart b/lib/panels/config_panel_widget.dart index 64702e1..05b8524 100644 --- a/lib/panels/config_panel_widget.dart +++ b/lib/panels/config_panel_widget.dart @@ -9,164 +9,17 @@ class ConfigPanelWidget extends StatefulWidget { class _ConfigPanelWidgetState extends State { - int _locationInterval = LocationManager().defaultUpdateIntervalMinutes; - bool _locationTrackingEnabled = false; - @override void initState() { super.initState(); - _loadSettings(); } - _loadSettings() async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - await prefs.reload(); - SharedPreferences.getInstance().then((prefs) { - setState(() { - _locationTrackingEnabled = prefs.getBool("location-enabled") ?? false; - _locationInterval = prefs.getInt("location-interval") ?? LocationManager().defaultUpdateIntervalMinutes; - }); - }); - } - void incLocationInterval() { - if (_locationInterval < 720) { - setState(() { - _locationInterval = _locationInterval + 1; - }); - } - } - - void decLocationInterval() { - if (_locationInterval > 1) { - setState(() { - _locationInterval = _locationInterval - 1; - }); - } - } - - restart() { - eventBus.fire(ShowPopupDialogEvent( - title: "Are you sure you want to restart Home Assistant?", - body: "This will restart your Home Assistant server.", - positiveText: "Sure. Make it so", - negativeText: "What?? No!", - onPositive: () { - ConnectionManager().callService(domain: "homeassistant", service: "restart", entityId: null); - }, - )); - } - - stop() { - eventBus.fire(ShowPopupDialogEvent( - title: "Are you sure you want to STOP Home Assistant?", - body: "This will STOP your Home Assistant server. It means that your web interface as well as HA Client will not work untill you'll find a way to start your server using ssh or something.", - positiveText: "Sure. Make it so", - negativeText: "What?? No!", - onPositive: () { - ConnectionManager().callService(domain: "homeassistant", service: "stop", entityId: null); - }, - )); - } - - updateRegistration() { - MobileAppIntegrationManager.checkAppRegistration(showOkDialog: true); - } - - resetRegistration() { - eventBus.fire(ShowPopupDialogEvent( - title: "Waaaait", - body: "If you don't whant to have duplicate integrations and entities in your HA for your current device, first you need to remove MobileApp integration from Integration settings in HA and restart server.", - positiveText: "Done it already", - negativeText: "Ok, I will", - onPositive: () { - MobileAppIntegrationManager.checkAppRegistration(showOkDialog: true, forceRegister: true); - }, - )); - } @override Widget build(BuildContext context) { return ListView( children: [ - Card( - child: Padding( - padding: EdgeInsets.only(left: Sizes.leftWidgetPadding, right: Sizes.rightWidgetPadding), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ListTile( - title: Text("Mobile app integration", - textAlign: TextAlign.left, - overflow: TextOverflow.ellipsis, - style: new TextStyle(fontWeight: FontWeight.bold, fontSize: Sizes.largeFontSize)) - ), - Text("Registration", style: TextStyle(fontSize: Sizes.largeFontSize-2)), - Container(height: Sizes.rowPadding,), - Text("${HomeAssistant().userName}'s ${DeviceInfoManager().model}, ${DeviceInfoManager().osName} ${DeviceInfoManager().osVersion}"), - Container(height: 6.0,), - Text("Here you can manually check if HA Client integration with your Home Assistant works fine. As mobileApp integration in Home Assistant is still in development, this is not 100% correct check."), - //Divider(), - Row( - mainAxisSize: MainAxisSize.max, - children: [ - RaisedButton( - color: Colors.blue, - onPressed: () => updateRegistration(), - child: Text("Check registration", style: TextStyle(color: Colors.white)) - ), - Container(width: 10.0,), - RaisedButton( - color: Colors.redAccent, - onPressed: () => resetRegistration(), - child: Text("Reset registration", style: TextStyle(color: Colors.white)) - ) - ], - ), - Divider(), - Text("Location tracking", style: TextStyle(fontSize: Sizes.largeFontSize-2)), - Container(height: Sizes.rowPadding,), - Row( - children: [ - Text("Enable device location tracking"), - Switch( - value: _locationTrackingEnabled, - onChanged: (value) { - SharedPreferences.getInstance().then((prefs) => prefs.setBool("location-enabled", value)); - if (value) { - LocationManager().updateDeviceLocation(); - } - setState(() { - _locationTrackingEnabled = value; - }); - }, - ), - ], - ), - Container(height: Sizes.rowPadding,), - Text("Location update interval in minutes:"), - Row( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - //Expanded(child: Container(),), - FlatButton( - padding: EdgeInsets.all(0.0), - child: Text("+", style: TextStyle(fontSize: Sizes.largeFontSize)), - onPressed: () => incLocationInterval(), - ), - Text("$_locationInterval", style: TextStyle(fontSize: Sizes.largeFontSize)), - FlatButton( - padding: EdgeInsets.all(0.0), - child: Text("-", style: TextStyle(fontSize: Sizes.largeFontSize)), - onPressed: () => decLocationInterval(), - ), - ], - ) - ], - ), - ), - ), LinkToWebConfig(name: "Home Assistant configuration", url: ConnectionManager().httpWebHost+"/config"), ], ); @@ -174,7 +27,6 @@ class _ConfigPanelWidgetState extends State { @override void dispose() { - LocationManager().setSettings(_locationTrackingEnabled, _locationInterval); super.dispose(); } }